WPF 列表框绑定更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19906911/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:02:08  来源:igfitidea点击:

WPF ListBox Binding Update

c#wpfxamlbindinglistbox

提问by mmvsbg

I'm brand new to WPF and I just managed to bind a list of specific class items to a ListBox. The ListBox now successfully displays them. Here's some code, the class first:

我是 WPF 的新手,我只是设法将特定类项的列表绑定到 ListBox。ListBox 现在成功地显示它们。这是一些代码,首先是类:

public class OrderItem
{
    public int Quantity { get; set; }
    public string Name { get; set; }
    public Double Price { get; set; }
}

Some dummy data and the binding, which all happens in the constructor of the main program:

一些虚拟数据和绑定,所有这些都发生在主程序的构造函数中:

List<OrderItem> currentOrderItems = new List<OrderItem>();
        currentOrderItems.Add(new OrderItem() { Quantity = 5, Name = "Test", Price = 5 });
        currentOrderItems.Add(new OrderItem() { Quantity = 15, Name = "Test test", Price = 6.66 });
        currentOrderItems.Add(new OrderItem() { Quantity = 1, Name = "Test 3", Price = 15.88 });
        listOrderItems.ItemsSource = currentOrderItems;

And the XAML:

和 XAML:

<ListBox HorizontalAlignment="Left" Margin="150,27,0,23" Name="listOrderItems" Width="150" FontFamily="Times New Roman" FontSize="12">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="4">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Quantity}" FontWeight="Bold"  />
                    <TextBlock Grid.Column="1" Text="{Binding Name }" />
                    <TextBlock Grid.Column="2" Text="{Binding Price }" />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

My question is how can I update the ListBox to display a new item that I'm adding to the List containing the data a.k.a. the OrderItems. If I add, remove or modify the List in any way, this is not reflected in the ListBox. Thanks!

我的问题是如何更新 ListBox 以显示我添加到包含数据的列表中的新项目,即 OrderItems。如果我以任何方式添加、删除或修改 List,这不会反映在 ListBox 中。谢谢!

回答by Aleksey

For your case best way use mvvm patern. In brief: Your model OrderItem should implement interface INotifyPropertyChanged. If property changed, it notified about this. Then create viewmodel and set it in datacontext. In viewModel add ObservableCollectionwith OrderItems, this collection should notified view about changes in it. for more information read some articles like this: MVVM

对于您的情况,最好使用 mvvm 模式。简而言之:您的模型 OrderItem 应该实现接口INotifyPropertyChanged。如果属性发生变化,它会通知这一点。然后创建视图模型并将其设置在数据上下文中。在 viewModel 中添加ObservableCollection和 OrderItems,这个集合应该通知视图它的变化。有关更多信息,请阅读以下文章:MVVM

回答by gleng

Instead of using a List<OrderItem>use ObservableCollection<OrderItem>. This will notify that something was added/removed so your ListBox knows to refresh.

而不是使用List<OrderItem>use ObservableCollection<OrderItem>。这将通知添加/删除了某些内容,以便您的 ListBox 知道刷新。

Additionally, your OrderItemneeds to implement INotifyPropertyChangedand your setters need to call OnPropertyChanged.

此外,您OrderItem需要实现INotifyPropertyChanged并且您的设置者需要调用OnPropertyChanged.

回答by A. Morel

You can also rebind your ListBox in code behind:

您还可以在后面的代码中重新绑定您的 ListBox:

List<OrderItem> currentOrderItems = new List<OrderItem>();
currentOrderItems.Add(new OrderItem() { Quantity = 5, Name = "Test", Price = 5 });
currentOrderItems.Add(new OrderItem() { Quantity = 15, Name = "Test test", Price = 6.66 });
currentOrderItems.Add(new OrderItem() { Quantity = 1, Name = "Test 3", Price = 15.88 });

In code behind:

在后面的代码中:

private ObservableCollection<OrderItem> _OrderItemCollection;
public ObservableCollection<OrderItem> OrderItemCollection
{
    get
    {
        if (_OrderItemCollection == null)
            _OrderItemCollection = new ObservableCollection<OrderItem>();
        return _OrderItemCollection;
    }
    set => _OrderItemCollection = value;
}

private CollectionViewSource _OrderItemCollectionViewSource;
public ICollectionView OrderItemCollectionViewSource => _OrderItemCollectionViewSource.View;


public void loadData()
{
    _OrderItemCollectionViewSource = new CollectionViewSource();
    _OrderItemCollectionViewSource.Source = new ObservableCollection<OrderItem>(currentOrderItems) ;
    Binding b = new Binding("OrderItemCollectionViewSource") { Source = this };
    listOrderItems.SetBinding(ListBox.ItemsSourceProperty, b);
}

And the XAML:

和 XAML:

<ListBox HorizontalAlignment="Left" Margin="150,27,0,23" Name="listOrderItems" Width="150" FontFamily="Times New Roman" FontSize="12">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Margin="4">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Quantity}" FontWeight="Bold"  />
                <TextBlock Grid.Column="1" Text="{Binding Name }" />
                <TextBlock Grid.Column="2" Text="{Binding Price }" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>