Reputation: 15275
I want to be able to bind a ListBox
to a List<>
or ObservableCollection<>
and be able to change the List itself while keeping the binding.
In ViewModel:
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private ObservableCollection<string> items = new ObservableCollection<string>();
public ObservableCollection<string> Items
{
get
{
return items;
}
set
{
items = value;
RaisePropertyChangedEvent(nameof(Items));
}
}
private void FillItems()
{
Items1 = new ObservableCollection<string>();
Items.Add("1");
Items.Add("2");
}
in View:
<ListBox x:Name="listBox" ItemsSource="{Binding Items}"/>
Now when I call the FillItems()
function, the list won't show items. But if I change the code like below it will work:
private void FillItems()
{
Items.Clear();
Items.Add("1");
Items.Add("2");
}
Upvotes: 0
Views: 59
Reputation: 247323
Insure that the view model implements INotifyPropertyChanged
and notifies the view when ever the target property changes.
Using the following simple View
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ListBox x:Name="listBox" ItemsSource="{Binding Items}"/>
<Button Grid.Row="1" Content="Fill" Click="Button_Click" />
</Grid>
</Window>
Along with the following code behind and view model
namespace WpfApplication1 {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
private MainViewModel viewModel;
public MainWindow() {
InitializeComponent();
viewModel = new MainViewModel() {
Items = new List<string>() {
"a", "b"
}
};
this.DataContext = viewModel;
}
private void Button_Click(object sender, RoutedEventArgs e) {
viewModel.FillItems();
}
}
public class MainViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Random random = new Random();
private List<string> items = new List<string>();
public List<string> Items {
get {
return items;
}
set {
items = value;
RaisePropertyChangedEvent(nameof(Items));
}
}
public void FillItems() {
var list = Enumerable.Range(0, 10).Select(i => random.Next(100).ToString()).Distinct().ToList();
Items = new List<string>(list);
}
}
}
Every time the button was clicked the ListBox
was updated as expected for both List
and ObservableCollection
.
You should review your code again and make sure that the common practices that may be affecting your code are followed because what you provided in the example should work.
Upvotes: 1