我有一个WPF ListBox,我添加了一些'FooBar'对象作为项目(通过代码).FooBars不是WPF对象,只是带有覆盖ToString()函数的哑类.
现在,当我更改影响ToString的属性时,我想让ListBox更新.
谢谢...
Dre*_*kes 13
您的类型应该实现,INotifyPropertyChanged以便集合可以检测更改.正如萨姆所说,string.Empty作为论点传递.
您还需要将ListBox数据源设置为提供更改通知的集合.这是通过INotifyCollectionChanged接口(或不那么WPF IBindingList接口)完成的.
当然,INotifyCollectionChanged只要其中一个成员INotifyPropertyChanged项触发其事件,您就需要触发该接口.值得庆幸的是,框架中有一些类型可以为您提供此逻辑.可能是最合适的一个ObservableCollection<T>.如果您绑定ListBox到a,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>
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在XAML中控制对象所在的表示形式.
编辑1我注意到您的评论,您正在使用该ListBox.Items集合作为您的收藏.这不会做必需的绑定.你最好做以下事情:
var collection = new ObservableCollection<FooBar>();
collection.Add(fooBar1);
_listBox.ItemsSource = collection;
Run Code Online (Sandbox Code Playgroud)
我没有检查编译准确性的代码,但你得到了要点.
编辑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> { _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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
此处正确的解决方案是为 ListBox IetmsSource 属性使用ObservableCollection<>。WPF 将自动检测此集合内容中的任何更改,并强制相应的 ListBox 更新以反映更改。
您可能需要阅读这篇 MSDN 文章以获取更多信息。写它是为了专门解释如何处理这种情况
http://msdn.microsoft.com/en-us/magazine/dd252944.aspx?pr=blog
| 归档时间: |
|
| 查看次数: |
29487 次 |
| 最近记录: |