.net - 项目更改时更新 WPF 列表

标签 .net wpf listbox

我有一个 WPF 列表框,并且添加了一些“FooBar”对象作为项目(通过代码)。
FooBars 不是 WPF 对象,只是具有覆盖 ToString() 函数的哑类。

现在,当我更改影响 ToString 的属性时,我希望更新 ListBox。

  • 我怎样才能做到这一点“又快又脏”(比如重新粉刷)。
  • 依赖属性是解决这个问题的方法吗?
  • 是否值得/总是建议为我的 FooBars 创建一个 wpf 包装类?

  • 谢谢...

    最佳答案

    你的类型应该实现 INotifyPropertyChanged以便集合可以检测到更改。正如 Sam 所说,通过 string.Empty作为论据。

    您还需要拥有 ListBox的数据源是提供更改通知的集合。这是通过 INotifyCollectionChanged 完成的。接口(interface)(或不那么 WPF IBindingList 接口(interface))。

    当然,您需要 INotifyCollectionChanged每当成员之一 INotifyPropertyChanged 时触发的界面items 触发其事件。值得庆幸的是,框架中有一些类型可以为您提供这种逻辑。可能最合适的是ObservableCollection<T> .如果你绑定(bind)你的 ListBoxObservableCollection<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/

    相关文章:

    c# - .NET Core 设置 - 最佳实践

    .net - 学习避免年龄歧视的技能(特别是 .net)

    wpf - 如何防止 WPF 裁剪我的图像?

    c# - Windows 10 GridView 样式看起来仍然像 Windows 7

    python - 如何查看 Tkinter 中是否存在小部件?

    c# - 列表框 WPF : change foreground color of SelectedItem and keep Material Design?

    c# - 多次附加事件处理程序

    c# - 如何在将数据写入 Excel 时制作正确的日期格式

    wpf - 如何在 ItemsControl 中为 ContentControl 设置动画

    c# - ListBox 组中的垂直分隔符