2011-07-08 95 views
0

當我更改BindingList中項目中的屬性時,雖然基礎對象已更改,但更改不會傳播到ListBox。在BindlingList中更新ListBox中項目屬性的更改

public class MyClass : INotifyPropertyChanged 
{ 
    public override string ToString() 
    { 
     return this.Name; 
    } 

    #region Name 

    private string name; 

    public string Name 
    { 
     get 
     { 
      return this.name; 
     } 

     set 
     { 
      if (value == this.name) return; 

      this.name = value; 
      this.OnPropertyChanged("Name"); 
     } 
    } 

    #endregion 

    #region INotifyPropertyChanged event 

    ///<summary> 
    ///Occurs when a property value changes. 
    ///</summary> 
    public event PropertyChangedEventHandler PropertyChanged; 


    /// <summary> 
    /// Raises the <see cref="PropertyChanged"/> event for 
    /// a given property. 
    /// </summary> 
    /// <param name="propertyName">The name of the changed property.</param> 
    protected void OnPropertyChanged(string propertyName) 
    { 
     //validate the property name in debug builds 
     VerifyProperty(propertyName); 

     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 


    /// <summary> 
    /// Verifies whether the current class provides a property with a given 
    /// name. This method is only invoked in debug builds, and results in 
    /// a runtime exception if the <see cref="OnPropertyChanged"/> method 
    /// is being invoked with an invalid property name. This may happen if 
    /// a property's name was changed but not the parameter of the property's 
    /// invocation of <see cref="OnPropertyChanged"/>. 
    /// </summary> 
    /// <param name="propertyName">The name of the changed property.</param> 
    [Conditional("DEBUG")] 
    private void VerifyProperty(string propertyName) 
    { 
     Type type = this.GetType(); 

     //look for a *public* property with the specified name 
     PropertyInfo pi = type.GetProperty(propertyName); 
     if (pi == null) 
     { 
      //there is no matching property - notify the developer 
      string msg = "OnPropertyChanged was invoked with invalid property name {0}: "; 
      msg += "{0} is not a public property of {1}."; 
      msg = String.Format(msg, propertyName, type.FullName); 
      Debug.Fail(msg); 
     } 
    } 

    #endregion 
} 

和XAML

<Window x:Class="testBL.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <ListBox x:Name="myListBox"> 
     </ListBox> 
     <Button x:Name="changeButton" Click="changeButton_Click">Change an item</Button> 
    </StackPanel> 
</Window> 
+0

你的代碼不顯示任何'BindingList's – Jay

回答

1

由於您將ListBox綁定到集合,因此每個ListBoxItem的默認數據上下文都是該實例。該集合例如是ObservableCollection<MyClass>,並且每個ListBoxItem的數據上下文是MyClass實例。

由於您尚未提供數據模板,因此ListBoxItem"{Binding}"實際綁定,這會導致您的MyClass.ToString()方法被調用。由於ToString()不是屬性,因此不支持屬性更改通知。以這種方式使用綁定(綁定到ToString())僅適用於不可變對象。

的解決方案是爲您ListBoxItem這樣提供一個明確的綁定:

<ListBox.ItemTemplate> 
    <DataTemplate> 
     <TextBlock Text="{Binding Name}"/> 
    </DataTemplate> 
</ListBox.ItemTemplate> 

,或者讓你的MyClass對象不可變和替換他們,而不是他們變異的。

0

,需要在每個項目中的BindingList的NotifyPropertyChanged分配一個事件處理程序,當發生這種情況,在事件處理程序提出一個CollectionChanged事件。

我會推薦使用從ObservableCollection繼承的集合,並自動分配和刪除處理程序。我稱這是一個VeryObservableCollection。

相關問題