I have a ListBox
and a class with strings. Each time that a user clicks add button in the application, I create a new instance of the class and add it to the list which is binded to the ListBox
. The first time I click the add button, the list box shows the first item, but the next time it doesn't show two items.
XAML - this is the 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}"/>
The code behind:
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;
}
Where is my mistake?
WPF does not know when your collection is changing. The problem is here:
List<Class_ListViewItem> List_ListBoxItems = new List<Class_ListViewItem>();
you need to change the list to
ObservableCollection<Class_ListViewItem> List_ListBoxItems = new ObservableCollection<Class_ListViewItem>();
ObservableCollection (System.Collections.ObjectModel) throws an event when the collection is changed, so that WPF can update the listbox.
Also, you can remove the following line, or move it to the constructor of your control.
ListBox_BinsRegion.DataContext = List_ListBoxItems;
When you assign the DataContext the second time, it doesn't technically change. This is because you are assigning it to the same collection. You should do something like this instead:
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);
}
You should not change the DataContext of the control, instead set the binding to theList_ListBoxItems and make it a public property, and use an ObservableCollection or BindableCollection instead of list
Use an ObservableCollection<> rather than a List<>. This will update the binding automatically, with no need for the following line (which can be kind of slow)
ListBox_BinsRegion.DataContext = List_ListBoxItems;
You could either do what everyone else already suggested (using an ObservableCollection instead of the List) - or you could query the dependency property which is bound and find the corresponding Binding and refresh it manually.
I'd go for the ObservableCollection :)