Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListBox doesn't refresh after property changed

I'm trying to bind two ListBoxes:

<ListBox SelectionChanged="lbApplications_SelectionChanged"
         ItemsSource="{Binding Path=Applications, 
                       UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
<ListBox DisplayMemberPath="Message" 
         ItemsSource="{Binding Path=Events, 
                       UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />

Applications and Events are public properties in Window class.

I set DataContext to this to both list boxes and implement INotifyPropertyChanged in Window class:

 private void NotifyPropertyChanged(string info)
 {
   if (PropertyChanged != null)
     PropertyChanged(this, new PropertyChangedEventArgs(info));
 }

And then after adding new item to Applications or Events I call:

 NotifyPropertyChanged("Events");
 NotifyPropertyChanged("Applications");

The issue is that ListBox is loaded only one time. What am I doing wrong?

like image 506
Jan Remunda Avatar asked Jul 14 '09 07:07

Jan Remunda


2 Answers

Let's just look at one of the ListBoxes, since they're both the same, basically.

The code we're concerned about is this:

<ListBox ItemsSource="{Binding Path=Applications, 
                           UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />

Since you're new to WPF, let me say you probably don't need UpdateSourceTrigger or Mode in there, which leaves us with this:

<ListBox ItemsSource="{Binding Path=Applications}" />

You mentioned that Applications is a public property in your code-behind. You need it to be a DependencyProperty, and you need it to fire events when it changes -- most people use an ObservableCollection for this.

So your code-behind will have something like this:

public ObservableCollection<string> Applications
{
    get { return (ObservableCollection<string>)GetValue(ApplicationsProperty); }
    set { SetValue(ApplicationsProperty, value); }
}

public static readonly DependencyProperty ApplicationsProperty =
    DependencyProperty.Register("Applications", 
    typeof(ObservableCollection<string>), typeof(Window1), 
    new UIPropertyMetadata(null));

Then, where you want to add it, you'll do something like this:

this.Applications = new ObservableCollection<string>();
Applications.Add("Whatever");

Finally, for the "simple" binding syntax to work in the XAML, I usually change the DataContext in my Window (or the root Control element for the file, whatever I'm working in) to

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}" ... >
   ...

Your Applications box will update automatically.

like image 196
exclsr Avatar answered Oct 31 '22 11:10

exclsr


The problem is that your property value hasn't changed. It's still the same list, same reference.

One solution might be that your collections are of type ObservableCollection. These lists provide events for WPF when you add or remove items.

like image 39
Arcturus Avatar answered Oct 31 '22 10:10

Arcturus