【问题标题】:Windows Store App Development - InvalidateRequerySuggestedWindows 应用商店应用开发 - InvalidateRequerySuggested
【发布时间】:2013-02-17 21:01:46
【问题描述】:

在我使用过的常规 WPF 项目中

CommandManager.InvalidateRequerySuggested();

为了强制再次执行值转换器。

现在,在 Windows 应用商店应用程序开发中,这个方便的命令不再可用。 是否存在等效的命令或其他可以解决问题的命令?

非常感谢您的帮助!

【问题讨论】:

  • 强制执行值转换器?那你不应该使有问题的财产无效吗?当我需要不再运行值转换器时,我使用 CommandManager.InvalidateRequerySuggested 使命令 CanExecute 状态无效。这就是你所追求的吗?
  • 是的,完全正确。值转换器只是另一个我想无效的地方。
  • 在更新命令的情况下,我认为您必须自己在 Windows 商店应用程序中推出该功能。基本上,旧命令将可执行更改事件委托给 RequerySuggested 事件。自己也可以做类似的事情。
  • 我也担心这个好用又方便的命令必须手动重新实现。感谢您确认我的印象。

标签: c# windows-store-apps ivalueconverter


【解决方案1】:

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版本通过实现CanExecuteChanged间接使用CommandManager.InvalidateRequerySuggested,如下:

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

但是,在 WinRT 中,这不受支持,在我的 WinRT 版本中,任何使委托命令的状态无效的代码都必须调用 Refresh 方法以导致视图中的绑定项重新查询命令。

我认为针对您的特定问题的最佳解决方案是在您的视图模型中实现INotifyPropertyChanged。在此接口上调用PropertyChanged 事件相当于我的Refresh 方法,并强制视图中的绑定元素重新评估自身,从而重新运行所有关联的IValueConverter 实例。

【讨论】:

    【解决方案2】:

    根据 Microsoft Developer Network,它确实适用于 Windows 8 和 Framework 4.5。但是,它确实声明了以下内容:

    CommandManager 只关注特定条件 确定命令目标何时发生变化,例如 键盘焦点。在 CommandManager 不支持的情况下 充分确定导致命令的条件变化 无法执行,可以调用 InvalidateRequerySuggested 强制 CommandManager 引发 RequerySuggested 事件。

    但由于它没有提到 Windows Mobile 兼容 WinRT 以下的 Windows 设备,因此上述命令可能不适用于这些设备,但如果它适用于 WinRT 和 Windows 8 的 Windows Store,它应该可以正常工作。

    如果我误解了您的问题,请告诉我,我会尽力提供进一步帮助。

    Article about command here:

    【讨论】:

    • 感谢您的回复,格雷格。但可悲的是,您甚至无法引用 PresentationCore.dll / 使用 System.Windows.Input 命名空间,因为它们与 Windows Store 项目不兼容。
    • 真的,这看起来很奇怪。稍后我会测试一下,看看我想出了什么
    猜你喜欢
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多