2013-08-19 6 views
6

wpfウィンドウにカスタムの編集可能なリストボックスがあります。プロパティはそのように見えた変更を 私はまたのviewmodelクラスを持っている:getアクセサのみでプロパティにバインドする方法

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

私の質問を更新する方法である割引:

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

だから、私は、このプロパティに私の保存]ボタンをバインドしたいと思いますリストボックスの行の1つが変更された場合は、ボタンをクリックしますか?

答えて

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 
} 

あなたはその後、データバインド、このようなボタンにすることができます

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

左いただきましたごのviewmodelにICommandプロパティを宣言している:

public ICommand MyCommand { get; private set; } 

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

ボタンの状態は、ほとんどの変更で自動的に更新されます。何らかの理由でそれができない場合は、CommandManager.InvalidateRequerySuggested

1

あなたのViewModelはINotifyPropertyChangedを実装する必要があり、これまであなたがcustomers

アップデートでお客様を変更したときにHasChangesためにPropertyChangedイベントを発生させる必要があります。お客様はINotifyPropertyChangedの顧客を実装した場合、それは自己が観測コレクションです

。あなたは購読することができます。また、購読解除のアクションによっては、customersコレクションのCollectionChangedEventのすべての顧客に購読することができます。

0

ViewModelでINotifyPropertyChangedが実装されている場合は、HasChangesでOnPropertyChanged()メソッドを呼び出すだけで済みます。 Prismでは、同等のメソッドはRaisePropertyChangedです。

しかし、MVVMでは、ボタンのコマンドプロパティにバインドされているコマンドの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

ボタンが何らかの形で通知を受け取る必要があります。このように、顧客が変更されるたびに通知を送信する必要があります。あなたの場合、あなたのビューモデルにINotifyPropertyChangedインターフェースを実装するでしょう。 "リストボックスの行が変更された"ときは、 "HasChanges"プロパティのPropertyChangedイベントを発生させる必要があります。変更はあなたには気付かれるはずですが、そこではイベントが発生するはずです。 あなたはビューモデルを持っているので、ボタンでコマンドを使うことができます。また、CanExecuteはロジックがtrueまたはfalseを返すようになります。変更があったときにマークする必要があります。

関連する問題