2013-08-19 31 views
6

我有我的wpf窗口上的一些自定義可編輯列表框。 我也有一個視圖模型類屬性更改它看起來像:如何綁定屬性只有獲得訪問器

public bool HasChanges 
{ 
    get 
    { 
     return customers.Any(customer => customer.Changed); 
    } 
} 

所以,我想我的保存按鈕綁定到這個屬性:

<Button IsEnabled="{Binding HasChanges, Mode=OneWay}"... 

我的問題是如何更新保存如果其中一個列表框行被更改,按鈕?

回答

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 
} 

然後,您可以數據綁定到按鈕這樣的:

public ICommand MyCommand { get; private set; } 

//in constructor: 
MyCommand = new RelayCommand(_ => SomeActionOnButtonClick(), _ => HasChanges); 

<Button Command="{Binding MyCommand}" .../> 

請告訴我剩下的就是你的視圖模型聲明ICommand財產然後按鈕的狀態會自動更新大部分更改。如果它不是由於某種原因 - 您可以致電CommandManager.InvalidateRequerySuggested

1

您的視圖模型應該實現INotifyPropertyChanged,應提高PropertyChanged事件爲HasChanges當你採customers

更新更改客戶:

如果客戶執行INotifyPropertyChanged客戶它的自我是一個觀察的集合。您可以訂閱並根據取消訂閱的行爲,向customers集合的CollectionChangedEvent中的所有客戶訂閱。

0

如果你的ViewModel實現了INotifyPropertyChanged,你只需要在HasChanges上調用OnPropertyChanged()方法。對於Prism,等效方法是RaisePropertyChanged。

但是,對於MVVM,您可能希望將該測試放入綁定到您的按鈕Command屬性的命令的CanExecute方法中。這將自動處理IsEnabled。

2

爲了讓WPF對屬性的變化做出反應,該類必須實現INotifyPropertyChanged接口。每次客戶更改時都需要發送通知,如下所示:

class CustomerList : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 
    private List<Customer> customers = ... 
    public bool HasChanges { 
     get { 
      return customers.Any(customer => customer.Changed); 
     } 
    } 
    // Callers who change customers inside your list must call this method 
    public void ChangeCustomer(Customer c) { 
     // Do whatever you need to do, ... 
     ... 
     // then send out the notification to WPF 
     OnPropertyChanged("HasChanges"); 
    } 
    protected void OnPropertyChanged(string name) { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 
0

按鈕不知何故必須接收通知。在你的情況下,你可能在viewmodel中實現INotifyPropertyChanged接口。當您的「列表框行被更改」時,您應該引發「HasChanges」屬性的PropertyChanged事件。但是,在你的viewmodel中應該注意到變化,並且應該引發事件。 作爲一個不同的解決方案,因爲你有一個視圖模型,你可以在你的按鈕上使用一個命令,並且CanExecute可以讓邏輯返回真或假,當發生變化時也必須由你標記。