Windows Store应用程序开发 - InvalidateRequerySuggested

3

在常规的WPF项目中,我使用了

CommandManager.InvalidateRequerySuggested();

为了强制再次执行值转换器。
现在,在Windows Store应用程序开发中,这个方便的命令不再可用。是否存在等效的命令或其他可以完成此任务的东西?
非常感谢您的帮助!

强制执行值转换器?难道不应该使相关属性无效吗?我使用CommandManager.InvalidateRequerySuggested来使命令的CanExecute状态无效,以便在需要时不再运行值转换器。这是你想要的吗? - Just another metaprogrammer
是的,没错。我也想使值转换器失效。 - robert.oh.
1
在更新命令方面,我认为你必须在Windows商店应用程序中自己实现该功能。基本上,旧的命令将can execute更改事件委托给RequerySuggested事件。自己做类似的事情是可能的。 - Just another metaprogrammer
我也担心这个方便好用的命令必须手动重新实现。感谢您确认我的印象。 - robert.oh.
2个回答

3

CommandManager 在 WinRT 中不存在。您需要手动刷新侦听器。以下是我示例实现的 DelegateCommand<T>,它说明了这一点:

using System;
using System.Windows.Input;

public class DelegateCommand<T> : ICommand
{
    private readonly Action<T> m_executeAction;
    private readonly Predicate<T> m_canExecutePredicate;

    public DelegateCommand(Action<T> executeAction)
        : this(executeAction, null)
    {
    }

    public DelegateCommand(Action<T> executeAction, Predicate<T> canExecutePredicate)
    {
        if (executeAction == null)
        {
            throw new ArgumentNullException("executeAction");
        }

        m_executeAction = executeAction;
        m_canExecutePredicate = canExecutePredicate;
    }

    public event EventHandler Executed;

    public event EventHandler CanExecuteChanged;

    bool ICommand.CanExecute(object parameter)
    {
        return CanExecute((T)parameter);
    }

    void ICommand.Execute(object parameter)
    {
        Execute((T)parameter);
    }

    public bool CanExecute(T parameter)
    {
        var result = true;
        var canExecutePredicate = m_canExecutePredicate;
        if (canExecutePredicate != null)
        {
            result = canExecutePredicate(parameter);
        }
        return result;
    }

    public void Execute(T parameter)
    {
        m_executeAction(parameter);
        RaiseExecuted();
    }

    public void Refresh()
    {
        RaiseCanExecuteChanged();
    }

    protected virtual void RaiseExecuted()
    {
        var handler = Executed;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }

    protected virtual void RaiseCanExecuteChanged()
    {
        var handler = CanExecuteChanged;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

此类的 WPF 版本间接使用 CommandManager.InvalidateRequerySuggested,通过以下方式实现 CanExecuteChanged:

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

然而,在WinRT中,这不被支持,在我的WinRT版本中,任何使委托命令状态无效的代码都必须调用Refresh方法,以使视图中绑定的项目重新查询命令。
我认为解决您特定问题的最佳方案是在您的视图模型中实现INotifyPropertyChanged。调用此接口上的PropertyChanged事件等同于我的Refresh方法,强制视图中的绑定元素重新评估自身,并因此重新运行所有相关的IValueConverter实例。

0
根据微软开发者网络的说法,它可以在Windows 8和Framework 4.5上运行。但是,它确实指出了以下内容:
CommandManager仅在确定命令目标何时更改时关注某些条件,例如键盘焦点的更改。在CommandManager无法充分确定导致命令无法执行的条件更改的情况下,可以调用InvalidateRequerySuggested来强制CommandManager引发RequerySuggested事件。
但由于它没有提到符合Windows RT以下WinRT的Windows设备的情况,因此该命令可能无法在这些设备上工作,但如果它是针对WinRT和Windows 8的Windows Store,则应该可以正常工作。
如果我误解了您的问题,请告诉我,我会尽力提供帮助。 有关此命令的文章:

谢谢你的回复,Greg。但是令人遗憾的是,你甚至不能引用PresentationCore.dll / 使用System.Windows.Input命名空间,因为它们与Windows Store项目不兼容。 - robert.oh.
真的很奇怪。我稍后会测试一下,看看我能得出什么结果。 - Greg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接