In wpf Clear ListBox items at Runtime

2019-09-16 10:44发布

问题:

I am using wpf listbox, i cannot able to clear the list when am calling the reload data function, i just want to reload new data at runtime,while page loading it loads the data correctly, when i refresh the new data is fetched in itemsource i can see that in debug mode, but no new data in listbox, old data remains in the list, i cant even clear, when i call list.items.clear(), i tried lot ways, is there any problem in my XAML binding, the following is my code.

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>

Get the list of values

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

// Here define the actual binding of the userinterface listbox to the in-memory list of objects.

 foreach (DtoProjectsRow row in projectsTable.Rows)
                {

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

  lstbxindex.DataContext = projectInformationList1;

In SO I tried some solution but unfortunately it is not work for me. Last I tried,

XAML.cs page

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

Using this above solution listitems are clear but when pageloading the listboxitems are clear but I don't want to clear the iistboxitems, after updating the values from user it will reload the updated value in listbox.

lstbxindex.ItemsSource = null;

But its not work.For pageload listbox loaded all items,every 15 min interval it will call the load function for firsttime it will reload the updatedvalues but second time it will reload the updated values and previous values remains in listbox again.

回答1:

I misunderstood initially thinking you were using MVVM, instead you're populating the ListView datasource from code behind.

Your line lstbxindex.DataContext = projectInformationList1; does not set the Data as you'd think. Instead try lstbxindex.DataContext = this; which means you're telling your view to look for the data source in code behind.

As such, I suggest adding using System.ComponentModel; and using BindingList, a comparison is here.

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

And you just need this once:

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

As mentioned in the comments, if you did not use ItemsSource="{Binding projectInformationList1}" as I suggested in a comment to your question, this is the alternative:

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

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


回答2:

You should have a view model class with a collection property, e.g. like this:

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

Set the DataContext of your Window or Page in XAML like this:

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

and bind the ListBox like this:

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

To clear all items in the source collection, access the DataContext in code behind:

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

Edit: Instead of assigning the DataContext in XAML, you may as well do it in code behind, even before the Page or Window is initialized:

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


回答3:

Added the line in loadfunction, Initially set null for ItemSource and then set null to the list object

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

it will clear the listboxitems and reload with updated values only.

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