我有一个WPF ListBox,我添加了一些'FooBar'对象作为项目(通过代码).FooBars不是WPF对象,只是带有覆盖ToString()函数的哑类.
现在,当我更改影响ToString的属性时,我想让ListBox更新.
我该怎么做'快而脏'(如重画).
依赖属性是否可以继续?
是否值得/总是可取的,为我的FooBars创建一个wpf包装类?
谢谢...
您的类型应该实现,INotifyPropertyChanged
以便集合可以检测更改.正如萨姆所说,string.Empty
作为论点传递.
您还需要将ListBox
数据源设置为提供更改通知的集合.这是通过INotifyCollectionChanged
接口(或不那么WPF IBindingList
接口)完成的.
当然,INotifyCollectionChanged
只要其中一个成员INotifyPropertyChanged
项触发其事件,您就需要触发该接口.值得庆幸的是,框架中有一些类型可以为您提供此逻辑.可能是最合适的一个ObservableCollection
.如果您绑定ListBox
到a,ObservableCollection
那么事件链接将自动发生.
在相关的说明中,您不必使用ToString
方法只是为了让WPF以您想要的方式呈现对象.你可以使用DataTemplate
这样的:
通过这种方式,您可以在XAML中控制对象所在的表示形式.
编辑1我注意到您的评论,您正在使用该ListBox.Items
集合作为您的收藏.这不会做必需的绑定.你最好做以下事情:
var collection = new ObservableCollection(); collection.Add(fooBar1); _listBox.ItemsSource = collection;
我没有检查编译准确性的代码,但你得到了要点.
编辑2使用DataTemplate
上面给出的(我编辑它以适合您的代码)修复了问题.
看起来奇怪的是,触发PropertyChanged
不会导致列表项更新,但是然后使用该ToString
方法并不是WPF的工作方式.
使用此DataTemplate,UI可以正确绑定到确切的属性.
我在这里问了一个关于在WPF绑定中进行字符串格式化的问题.你可能会发现它很有帮助.
编辑3我很困惑为什么这仍然不适合你.这是我正在使用的窗口的完整源代码.
代码背后:
using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; namespace StackOverflow.ListBoxBindingExample { public partial class Window1 { private readonly FooBar _fooBar; public Window1() { InitializeComponent(); _fooBar = new FooBar("Original value"); listBox1.ItemsSource = new ObservableCollection{ _fooBar }; } private void button1_Click(object sender, RoutedEventArgs e) { _fooBar.Property = "Changed value"; } } public sealed class FooBar : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string m_Property; public FooBar(string initval) { m_Property = initval; } public string Property { get { return m_Property; } set { m_Property = value; OnPropertyChanged("Property"); } } private void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } }
XAML: