如何清空WPF列表框?

4

我正在使用WPF列表框,但在调用reload data函数时无法清除列表,我只想在运行时重新加载新数据,当页面加载时,它能够正确加载数据,当我刷新时,新数据是从itemsource中获取的,我可以在调试模式下看到,但列表框中没有新数据,旧数据仍然存在于列表中,我甚至无法清除,当我调用list.items.clear()时,它会抛出异常并导致应用程序崩溃,我尝试了很多方法,是否我的XAML绑定存在问题?以下是我的代码:

<DataTemplate x:Key="listBoxTemplate">
                <StackPanel Margin="3">
                    <DockPanel >
                        <TextBlock FontWeight="Bold" Text="{Binding Name}" DockPanel.Dock="Left" Margin="5,0,10,0"/>
                        <TextBlock Text="  " />
                         <TextBlock Text="{Binding Percnt}" Foreground="Green" FontWeight="Bold" />
                   </DockPanel>                       
                </StackPanel>
            </DataTemplate>

我的列表框

 <ListBox Height="898" Name="lstEntity" Width="291" ItemTemplate="{StaticResource listBoxTemplate}" SelectionChanged="lstEntity_SelectionChanged"/>

绑定代码
   lstEntity.ItemsSource = sei.getNames();

getNames()函数只是返回数据列表,没有什么特殊的代码。如何解决这个问题。


当您尝试清除列表框并将其ItemsSource设置为null时,会出现哪些异常?您是否使用其他线程? - Amsakanna
5个回答

4

获取此类型行为的最佳方法是使用DependencyProperty和绑定。

在您的类文件中,可以像这样创建DP:

    #region MyList dependency property
    public static readonly DependencyProperty MyListProperty = DependencyProperty.Register("MyList", typeof(ObservableCollection<String>), typeof(Window1));

    public ObservableCollection<String> MyList
    {
        get { return (ObservableCollection<String>) GetValue(MyListProperty); }
        set { SetValue(MyListProperty, value); }
    }
    #endregion

然后在您的XAML中像这样绑定到该DP:
<ListBox ItemSource={Binding Path=MyList, ElementName=MyWindow} Height="898" Name="lstEntity" Width="291" ItemTemplate="{StaticResource listBoxTemplate}" SelectionChanged="lstEntity_SelectionChanged"/>

在你的XAML文件中,"MyWindow"是根窗口的x:Name(当然也可以像MVVM模式一样使用数据上下文)

如果想要在代码中添加/删除项目,只需直接访问列表即可:

MyList.Clear();
MyList.Add("My New String");

当然,您还需要将集合的通用类型更改为自己的类...


1
在你做这个之前:
  lstEntity.ItemsSource = sei.getNames();

清空列表框的项源:
lstEntity.ItemsSource = "";

这将会抛出完全相同的异常,就像他将其设置为null一样。 - B.K.

1
你是通过直接向Items集合添加还是通过ItemsSource来填充ListBox的呢?
如果是后者,将ItemsSource设置为null,然后重新设置以重新加载。

1
如果我设置为NULL,它仍会抛出异常: “在使用ItemsSource时,操作无效。请使用ItemsControl.ItemsSource访问和修改元素。” 它也不起作用..???? - Spen D
我不是直接添加,只是通过ItemSource添加。 - Spen D
它想要表达的是更新最初绑定的属性。更新内存中的对象,这应该会更新UI。因此,通过使用ObservableCollection作为ItemSource,将集合属性分配给新值应该清除UI组件,调用add/remove应该更新它等。您不希望直接访问项目列表以修改集合;这样做会引发异常。另一个选项是自己实现INotifyPropertyChanged。 - Anthony Mason

1

在您提供异常和其他细节之前,无法确定问题的原因。但是可以建议更好的做法。

  1. 让您的getnames方法返回一个IEnumerable。
  2. 构造一个ObservableCollection。
  3. 将ItemsSource设置为创建的ObservableCollection。

现在,您可以更改ObservableCollection以查看ListBox中的更改。


0
如果您正在使用MVVM模式,请向ViewModel添加一个属性:
public IEnumerable Names {
    get { return sei.getNames() as IEnumerable; }
}

然后,在您的 XAML 中,将 ItemsSource 编码为:

<ListBox ... ItemsSource="{Binding Names}" ... />

每当您的名称列表内容发生更改时,请引发PropertyChanged事件;这将告诉WPF系统刷新您的ListBox:
PropertyChanged(this, new PropertyChangedEventArgs("Names");

我没有使用 MVVM 模式。只是普通的绑定。 - Spen D
然后,如果可以的话,请直接在您的类上实现该属性和INotifyPropertyChanged接口。 - Rob Perkins

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