2013-08-19 10 views
6

के साथ संपत्ति से जुड़ने के लिए मेरे पास मेरी wpf विंडो पर कुछ कस्टम संपादन योग्य सूची बॉक्स है। मैं भी एक viewmodel वर्ग संपत्ति के साथ बदल दिया है जो कि तरह दिखता है:केवल एक्सेसर

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

मेरा प्रश्न अपडेट करने का तरीका है सहेजें:

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

तो, मैं इस संपत्ति के लिए मेरी सहेजें बटन बाध्य करने के लिए चाहते हैं बटन सूची पंक्तियों में से एक बदल गया है तो बटन?

उत्तर

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 
} 

फिर आप DataBind इस तरह बटन के लिए कर सकते हैं::

public ICommand MyCommand { get; private set; } 

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

:

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

क्या छोड़ दिया अपने viewmodel पर एक ICommand संपत्ति घोषित करने के लिए कर रहा है यहाँ मेरी समाधान से एक उदाहरण है बटन की स्थिति तब अधिकांश परिवर्तनों पर स्वचालित रूप से अपडेट हो जाएगी। अगर यह किसी कारण से नहीं है - तो आप CommandManager.InvalidateRequerySuggested

पर कॉल करके अपडेट को मजबूर कर सकते हैं
1

आपका ViewModel INotifyPropertyChanged को लागू करना चाहिए और जब कभी आप में customers

अद्यतन एक ग्राहक को बदलने HasChanges के लिए PropertyChanged घटना उठाना चाहिए:

तो ग्राहकों को लागू INotifyPropertyChanged और ग्राहकों यह स्वयं एक नमूदार संग्रह है। आप अपने customers संग्रह के CollectionChangedEvent के सभी ग्राहकों को, सदस्यता समाप्त करने के आधार पर सदस्यता ले सकते हैं।

0

यदि आपका व्यूमोडल INotifyProperty लागू करता है, तो आपको HasChanges पर OnPropertyChanged() विधि को कॉल करने की आवश्यकता है। प्रिज्म के साथ, बराबर विधि RaisePropertyChanged है।

हालांकि, एमवीवीएम के साथ, आप उस परीक्षा को अपने कमांड की 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 में तर्क वास्तविक या गलत लौटा होगा, जो परिवर्तन होने पर भी आपके द्वारा चिह्नित किया जाना चाहिए।

संबंधित मुद्दे