【问题标题】:In wpf Clear ListBox items at Runtime在 wpf 在运行时清除 ListBox 项目
【发布时间】:2017-06-20 06:29:23
【问题描述】:

我正在使用 wpf listbox, 在调用重新加载数据函数时无法清除列表,我只想在运行时重新加载新数据,而页面加载时它会正确加载数据,当我刷新新数据时在 itemsource 中获取我可以看到在调试模式下,但列表框中没有新数据,旧数据保留在列表中,我什至无法清除,当我调用 list.items.clear() 时,我尝试了很多方法,有没有我的 XAML 绑定中的问题,以下是我的代码。

XAML:

 <ListBox  ItemsSource="{Binding}"   HorizontalContentAlignment="Left" x:Name="lstbxindex"  Foreground="White" FontSize="20px" Height="400" BorderBrush="#555555" Margin="10,34,16,0" VerticalAlignment="Top" Width="322" Background="#555555" >
            <ListBox.ItemTemplate>    
                <DataTemplate>

                    <WrapPanel Orientation="Horizontal" Margin="5" >

                        <StackPanel Orientation="Horizontal">
                            <TextBlock x:Name="txtblckroundhour" Height="40px" Width="55px" Text="{Binding RoundedHours}"  FontSize="14" Background="#555555" Loaded="txtblckroundhour_Loaded"  Foreground="White"></TextBlock>

                            <Label x:Name="items" MouseDoubleClick="items_MouseDoubleClick" Content="{Binding ProjectRow.Name}" Background="#555555" FontSize="20" Loaded="items_Loaded" Visibility="Visible"  Margin="35,0,0,0"  Width="230" Foreground="White"></Label>
                        </StackPanel>


                        <StackPanel Orientation="Vertical">
                            <ComboBox  Height="40px" Width="290" Margin="-230,0,0,0" Loaded="ComboBox_Loaded" Visibility="Hidden"  IsEditable="True"  FontSize="20"  Background="White"  Foreground="Black"></ComboBox>
                        </StackPanel>

                        <!--<ComboBox  x:Name="ComboBox_AddItem"  Height="40px" Width="290" Margin="-35,35,0,0"  Loaded="ComboBox_AddItem_Loaded"  IsEditable="True"  FontSize="20"  Background="White" Visibility="Hidden" Foreground="Black"></ComboBox>-->
                    </WrapPanel>
                </DataTemplate>



            </ListBox.ItemTemplate>
        </ListBox>

获取值列表

private List<ProjectInformation> projectInformationList1 = new List<ProjectInformation>();

// 这里定义用户界面列表框到内存中对象列表的实际绑定。

 foreach (DtoProjectsRow row in projectsTable.Rows)
                {

                    projectInformationList1.Add(new ProjectInformation(row));
                }

  lstbxindex.DataContext = projectInformationList1;

在 SO 我尝试了一些解决方案,但不幸的是它不适合我。上次我试过了,

XAML.cs 页面

public static readonly DependencyProperty MyListProperty = DependencyProperty.Register("MyList", typeof(ObservableCollection<String>), typeof(Window));

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

XAML:

 <ListBox  ItemsSource="{Binding **ElementName=Window**}"   HorizontalContentAlignment="Left" x:Name="lstbxindex"  Foreground="White" FontSize="20px" Height="400" BorderBrush="#555555" Margin="10,34,16,0" VerticalAlignment="Top" Width="322" Background="#555555" >

使用上面的解决方案列表项很清晰,但是当页面加载列表框项很清晰但我不想清除 iistboxitems,在从用户更新值后它将重新加载列表框中的更新值。

lstbxindex.ItemsSource = null;

但它不起作用。对于加载所有项目的页面加载列表框,每 15 分钟间隔它会调用加载函数,第一次它会重新加载更新的值,但第二次它会重新加载更新的值,并且以前的值再次保留在列表框中。

【问题讨论】:

  • 抛出了什么异常?
  • 你遇到了什么异常?
  • 没有抛出异常。它只是在列表框中再次重新加载整个数据(更新值)。
  • 有几件事,先别做lstbxindex.ItemsSource = null;。如果您有 ViewModel,请不要使用后面的代码,因为它会让人感到困惑。你声明private List&lt;ProjectInformation&gt; projectInformationList1 = new List&lt;ProjectInformation&gt;();,但在你的foreach中你使用projectInformationList.Add(new ProjectInformation(row));,这是一个错字吗?最后,尝试像 ItemsSource="{Binding projectInformationList1, Mode=TwoWay}" 这样的双向绑定
  • @keyurPATEL 但它会在页面加载时清除 listboxitem。

标签: c# wpf xaml listbox textblock


【解决方案1】:

我误解了最初以为您使用的是 MVVM,而不是您从后面的代码填充 ListView 数据源。

您的lstbxindex.DataContext = projectInformationList1; 行没有按照您的想法设置数据。而是尝试lstbxindex.DataContext = this;,这意味着您正在告诉您的视图在后面的代码中查找数据源。

因此,我建议添加using System.ComponentModel;并使用BindingList,比较是here

private BindingList<ProjectInformation> projectInformationList1 = new BindingList<ProjectInformation>();

你只需要一次:

foreach (DtoProjectsRow row in projectsTable.Rows)
{
    projectInformationList1.Add(new ProjectInformation(row));
}
lstbxindex.DataSource = projectInformationList1;

如 cmets 中所述,如果您没有按照我在对您的问题的评论中建议的那样使用 ItemsSource="{Binding projectInformationList1}",则可以选择以下方法:

private ObservableCollection<ProjectInformation> projectInformationList1 = new ObservableCollection<ProjectInformation>();

foreach (DtoProjectsRow row in projectsTable.Rows)
{
    projectInformationList1.Add(new ProjectInformation(row));
}
lstbxindex.DataContext = projectInformationList1;

【讨论】:

  • lstbxindex.DataContext = this 不能与 ItemsSource="{Binding}" 一起使用。
  • 并使用 ObservableCollection 代替 BindingList
  • @Keyur PATEL 谢谢,但现在显示无效操作异常被抛出
  • 扔在哪一行?
  • 在滚动列表框时,它会添加更新的值,之前的值保持不变。然后它会显示 invalidOperationException。
【解决方案2】:

您应该有一个具有集合属性的视图模型类,例如像这样:

public class ViewModel
{
    public ObservableCollection<ProjectInformation> Projects { get; }
        = new ObservableCollection<ProjectInformation>();
}

像这样在 XAML 中设置窗口或页面的 DataContext:

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>

并像这样绑定 ListBox:

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

要清除源集合中的所有项目,请在后面的代码中访问 DataContext:

var vm = (ViewModel)DataContext;
vm.Projects.Clear();

编辑:除了在 XAML 中分配 DataContext,您还可以在后面的代码中进行,甚至在初始化页面或窗口之前:

public MainWindow()
{
    DataContext = new ViewModel();
    InitializeComponent();
}

【讨论】:

  • 在列表框中我有两个控件一个是文本块另一个是标签,在文本块内我要绑定项目。
  • 在 vm.Projects.Clear() 这一行中会抛出空引用异常
  • 使用调试器检查vm 是否为空或Projects 属性。
  • 我检查了 vm 是否为空
  • 那么您可能在加载 Page 或 Window 之前访问了 DataContext 属性。查看我的编辑。
【解决方案3】:

在loadfunction中添加了一行,最初为ItemSource设置null,然后将null设置为list对象

lstbx.ItemsSource=null;
 lstbx.Items.Clear();
  ProjectInfoList1=null;

它将清除列表框项并仅使用更新的值重新加载。

private BindingList<ProjectInfo> projectInfoList1 = new BindingList<ProjectInfo>();
        Public void loadfunction()
        {

        lstbx.ItemsSource=null;
        lstbx.Items.Clear();
        ProjectInformationList1=null;
        foreach (DtoProRow row in table.Rows)
        {
            projectInfoList1.Add(new ProjectInfo(row));
        }
        lstbx.DataContext = projectInfoList1;
        }

【讨论】:

  • 这没什么意义,因为设置 lstbx.ItemsSource = null 会使您在 XAML 中声明的 ItemsSource 绑定无效。请尝试了解数据绑定到集合的实际上在 WPF 中是如何工作的。阅读这些文章:Data Binding OverviewData Templating Overview。现在,你做错了。您在个人资料页面上写下Learning!!!,所以请听听专家告诉您的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多