如何仅使用get访问器绑定到属性

Ole*_*tov 6 c# wpf mvvm viewmodel

我的wpf窗口上有一些自定义的可编辑列表框.我还有一个带有Property Changed的viewmodel类,它看起来像这样:

public bool HasChanges
{
    get
    {
        return customers.Any(customer => customer.Changed);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我想将我的保存按钮绑定到此属性:

<Button IsEnabled="{Binding HasChanges, Mode=OneWay}"...
Run Code Online (Sandbox Code Playgroud)

我的问题是如果其中一个列表框行被更改,如何更新保存按钮?

Nik*_*a B 2

处理按钮的正确方法是实现ICommand接口。这是我的解决方案的一个示例:

public class RelayCommand : ICommand
{
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute) : this(execute, null)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;           
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

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

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

然后您可以像这样将数据绑定到按钮:

<Button Command="{Binding MyCommand}" .../>
Run Code Online (Sandbox Code Playgroud)

ICommand剩下的就是在视图模型上声明一个属性:

public ICommand MyCommand { get; private set; }

//in constructor:
MyCommand = new RelayCommand(_ => SomeActionOnButtonClick(), _ => HasChanges);
Run Code Online (Sandbox Code Playgroud)

然后,按钮的状态将根据大多数更改自动更新。如果由于某种原因没有 - 您可以通过调用强制更新CommandManager.InvalidateRequerySuggested