绑定到代码中(可能)空属性而不更新模型视图

本文关键字:属性 更新 视图 模型 代码 可能 绑定 | 更新日期: 2023-09-27 18:31:03

我有一个绑定到如下所示的 Singleton 属性:

<ComboBox ItemsSource="{Binding SourceList, UpdateSourceTrigger=PropertyChanged}" 
                                      SelectedItem="{Binding Source={x:Static local:MySingleton.Instance}, UpdateSourceTrigger=PropertyChanged, 
                                      Path=PossibleNullProperty.PossibleNullProperty.PossibleNullProperty.Source}" 
                                      Width="Auto" />

这非常有效,即使 PossibleNullProperty 为空,一旦它们发生变化,"Source"属性就会绑定到 ComboBox。

现在,我的模型视图中还有一个命令绑定,它绑定到视图模型中的委托命令。一旦 SelectedItem 发生更改,DelegateCommand 就应该引发 CanExecuteChangedEvent。

好吧,我无法在"源"属性所在的对象中引发此事件。所以我必须在视图模型中引发这个事件。我的想法是创建一个指向嵌套属性的属性,如下所示:

public string Source
    {
        get { return MySingleton.Instance.PossibleNullProperty?.PossibleNullProperty?.PossibleNullProperty?.Source; }
        set
        {
            MySingleton.Instance.PossibleNullProperty.PossibleNullProperty.PossibleNullProperty.Source = value;
            RaisePropertyChanged();
            MyCommand.RaiseCanExecuteChanged();
        }
    }

现在的问题是,在发生绑定时,链中的属性为 null,因此 ComboBox SelectedItem 无法"访问"源"属性。在应用程序运行时期间,这可能会更改,并且"Source"属性是"可访问的",但模型视图不会更新。

如何解决我的问题?

谢谢

绑定到代码中(可能)空属性而不更新模型视图

在视图模型中添加它,您将做得很好:

    CommandManager.RequerySuggested += CommandManager_RequerySuggested;
    private void CommandManager_RequerySuggested(object sender, EventArgs e)
    {
        this.MyCommand.CanExecute = "..." 
    }

每次 UI 更改都将调用CommandManager_RequerySuggested

!!!

由于此事件是静态的,因此它只会将处理程序作为弱引用保留。

不要忘记使用异步/等待:)

对于有同样问题的人来说,这就是我的 DelegateCommand 类现在的样子,它完美地工作,这要归功于开发刺猬的解决方案!

public class DelegateCommand<T> : System.Windows.Input.ICommand where T : class
{
    private readonly Predicate<T> _canExecute;
    private readonly Action<T> _execute;
    public DelegateCommand(Action<T> execute)
        : this(execute, null)
    {
    }
    public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
            return true;
        return _canExecute((T)parameter);
    }
    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}