仅显示一个项目的ListBox

3
我有一个 ListBox 和一个包含字符串的类。每次用户在应用程序中点击添加按钮时,我都会创建该类的新实例并将其添加到绑定到 ListBox 的列表中。第一次单击添加按钮时,列表框显示第一项,但下一次它不会显示两个项目。
XAML - 这是 ListBox
<ListBox Name="ListBox_BinsRegion" Height="181" Margin="233,16,6,94" Width="253" Background="Transparent" BorderThickness="1" BorderBrush="Black" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding}"/> 

代码背后的实现:

List<Class_ListViewItem> List_ListBoxItems = new List<Class_ListViewItem>();

 private void Button_Add_Click(object sender, RoutedEventArgs e)
    {
        Class_ListViewItem item = new Class_ListViewItem();
        item.WH = this.comboBox_WareHouseBinsRegionDefinition.SelectedItem.ToString();
        item.XXFrom = textBox_XXFrom.Text;
        item.XXTo = textBox_XXTo.Text;
        item.YYFrom = textBox_YYFrom.Text;
        item.YYTo = textBox_YYTO.Text;
        item.Z = textBox_ZFrom.Text;

        List_ListBoxItems.Add(item);

        ListBox_BinsRegion.DataContext = List_ListBoxItems;
    }

我的错误在哪里?


我刚刚做的是 - if (List_ListBoxItems.Count == 1) ListBox_BinsRegion.DataContext = List_ListBoxItems; ListBox_BinsRegion.Items.Refresh();现在它可以工作了... - N.D
如果您更喜欢这种方式,那也可以,而不仅仅使用可观察的集合。 - Josh G
5个回答

7

WPF 不知道你的集合何时发生了变化。问题就在这里:

List<Class_ListViewItem> List_ListBoxItems = new List<Class_ListViewItem>();

你需要将列表更改为

ObservableCollection<Class_ListViewItem> List_ListBoxItems = new ObservableCollection<Class_ListViewItem>();

ObservableCollection (System.Collections.ObjectModel) 会在集合发生更改时抛出一个事件,以便 WPF 可以更新列表框。

此外,您可以删除以下行,或将其移动到控件的构造函数中。

ListBox_BinsRegion.DataContext = List_ListBoxItems;

1
如果他删除DataContext行,则ListBox将没有任何项。 - CodeNaked
WPF 根据集合触发 CollectionChanged 事件来更新。如果您的集合没有实现 INotifyCollectionChanged 接口,则 WPF 集合将无法动态更新。 - Josh G

2

当您第二次分配DataContext时,它在技术上并没有改变。这是因为您将其分配给了相同的集合。您应该使用以下方式:

ObservableCollection<Class_ListViewItem> List_ListBoxItems = new ObservableCollection<Class_ListViewItem>();

public YourControl() {
    InitializeComponent();
    ListBox_BinsRegion.DataContext = List_ListBoxItems;
}

private void Button_Add_Click(object sender, RoutedEventArgs e)
{
    Class_ListViewItem item = new Class_ListViewItem();
    item.WH = this.comboBox_WareHouseBinsRegionDefinition.SelectedItem.ToString();
    item.XXFrom = textBox_XXFrom.Text;
    item.XXTo = textBox_XXTo.Text;
    item.YYFrom = textBox_YYFrom.Text;
    item.YYTo = textBox_YYTO.Text;
    item.Z = textBox_ZFrom.Text;

    List_ListBoxItems.Add(item);
}

1
你不应该改变控件的DataContext,而是将绑定设置为theList_ListBoxItems,并将其设置为公共属性,使用ObservableCollection或BindableCollection代替列表。

0
使用ObservableCollection<>而不是List<>。这将自动更新绑定,无需以下行(可能有点慢)。
ListBox_BinsRegion.DataContext = List_ListBoxItems;

他仍然需要在ListBox上设置数据上下文。如果没有它,绑定到集合的项源将无法工作。 - Josh G
1
是的,但他不需要每次向列表框添加内容时都这样做。 - MattS423

0

你可以选择其他人已经建议的做法(使用ObservableCollection而不是List)- 或者你可以查询绑定的依赖属性,并手动刷新相应的绑定。

我会选择ObservableCollection :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接