我有一个 WPF 列表框,并且添加了一些“FooBar”对象作为项目(通过代码)。
FooBars 不是 WPF 对象,只是具有覆盖 ToString() 函数的哑类。
现在,当我更改影响 ToString 的属性时,我希望更新 ListBox。
谢谢...
最佳答案
你的类型应该实现 INotifyPropertyChanged
以便集合可以检测到更改。正如 Sam 所说,通过 string.Empty
作为论据。
您还需要拥有 ListBox
的数据源是提供更改通知的集合。这是通过 INotifyCollectionChanged
完成的。接口(interface)(或不那么 WPF IBindingList
接口(interface))。
当然,您需要 INotifyCollectionChanged
每当成员之一 INotifyPropertyChanged
时触发的界面items 触发其事件。值得庆幸的是,框架中有一些类型可以为您提供这种逻辑。可能最合适的是ObservableCollection<T>
.如果你绑定(bind)你的 ListBox
到 ObservableCollection<FooBar>
那么事件链将自动发生。
在相关说明中,您不必使用 ToString
方法只是为了让 WPF 以您想要的方式呈现对象。您可以使用 DataTemplate
像这样:
<ListBox x:Name="listBox1">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:FooBar}">
<TextBlock Text="{Binding Path=Property}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
通过这种方式,您可以控制对象所属的对象的呈现方式——在 XAML 中。
编辑 1 我注意到您的评论说您正在使用
ListBox.Items
收藏为您的收藏。这不会进行所需的绑定(bind)。你最好做这样的事情:var collection = new ObservableCollection<FooBar>();
collection.Add(fooBar1);
_listBox.ItemsSource = collection;
我没有检查该代码的编译准确性,但你明白了要点。
编辑 2 使用
DataTemplate
我在上面给出了(我编辑它以适应你的代码)解决了这个问题。发射
PropertyChanged
似乎很奇怪不会导致列表项更新,但随后使用 ToString
方法不是 WPF 的预期工作方式。使用此 DataTemplate,UI 可以正确绑定(bind)到确切的属性。
不久前我在这里问了一个关于做 string formatting in a WPF binding 的问题.您可能会发现它很有帮助。
编辑 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> { _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:
<Window x:Class="StackOverflow.ListBoxBindingExample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StackOverflow.ListBoxBindingExample"
Title="Window1" Height="300" Width="300">
<DockPanel LastChildFill="True">
<Button Click="button1_Click" DockPanel.Dock="Top">Click Me!</Button>
<ListBox x:Name="listBox1">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:FooBar}">
<TextBlock Text="{Binding Path=Property}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
</DockPanel>
</Window>
关于.net - 项目更改时更新 WPF 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/553150/