WPF ListBox绑定更新

时间:2013-11-11 12:54:46

标签: c# wpf xaml binding listbox

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

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

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

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;

和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>

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

3 个答案:

答案 0 :(得分:6)

对于您的情况最好的方式使用mvvm patern。 简单来说: 您的模型OrderItem应实现接口 INotifyPropertyChanged 。 如果属性发生变化,则通知此事。 然后创建viewmodel并在datacontext中设置它。在viewModel中添加带有OrderItems的 ObservableCollection ,该集合应该通知视图有关其中的更改。 有关更多信息,请阅读以下文章:MVVM

答案 1 :(得分:4)

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

此外,您的OrderItem需要实施INotifyPropertyChanged,而您的提交者需要致电OnPropertyChanged

答案 2 :(得分:0)

您还可以在下面的代码中重新绑定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 });

在后面的代码中:

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);
}

还有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>