WPF如何在不重置项目的情况下更新绑定列表?

19 浏览
0 Comments

WPF如何在不重置项目的情况下更新绑定列表?

在一个简单的WPF XAML UI中显示了一个项目列表:

窗口x:Class="MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Height="450" Width="800">

数据在C#视图模型中:

使用System.ComponentModel;

使用System.Threading.Tasks;

使用System.Windows;

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

DataContext = this;

Items.Add(new MyItem());

Items.Add(new MyItem());

Items.Add(new MyItem());

Items.Add(new MyItem());

Loaded += async (s, e) =>

{

while (true)

{

await Task.Delay(1000); // 可能在此处更改项目

Items.ResetBindings(); // 让UI知道添加/删除/重新排序/修改的项目

}

};

}

public BindingList Items { get; } = new BindingList();

}

public class MyItem : INotifyPropertyChanged

{

public string Text { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

}

项目可以自动更改,因此调用Items.ResetBindings();可以在UI中显示这些更改。但这也会破坏UI:焦点和用户对当前项目的任何修改都会消失!

如何在不重置UI控件的情况下更新绑定列表?

0
0 Comments

问题出现的原因是在WPF中更新绑定列表时,可能会导致重置项。解决方法是通过正确触发属性更改事件来更新绑定列表,而不是调用Items.ResetBindings()方法。

具体解决方法如下:

1. 在MyItem类中实现INotifyPropertyChanged接口,确保属性更改时会触发PropertyChanged事件。

2. 在Text属性的set访问器中,添加PropertyChanged事件的触发代码。

3. 在MainWindow类中,不再调用Items.ResetBindings()方法。

4. 在Loaded事件处理程序中,使用异步循环定期添加新的MyItem实例到Items列表,并更新Text属性。

以下是完整的解决方案代码:

public class MyItem : INotifyPropertyChanged
{
    private string _text;
    public string Text
    {
        get { return _text; }
        set { _text = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text))); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Items.Add(new MyItem());
        Items.Add(new MyItem());
        Items.Add(new MyItem());
        Items.Add(new MyItem());
        Loaded += async (s, e) =>
        {
            while (true)
            {
                await Task.Delay(1000);
                Items.Add(new MyItem() { Text = "new" });
            }
        };
    }
    public BindingList Items { get; } = new BindingList();
}

以上解决方案中,我们通过正确地触发属性更改事件来更新绑定列表,而不是调用不必要的ResetBindings方法。这样可以确保将新的MyItem实例添加到Items列表时,UI能够正确地更新,而不会丢失其他状态(如选中项)。

0