2011-07-08 18 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と呼んでいます。

関連する問題