views:

3702

answers:

2

Hi,

i'm new in WPF so it's possible, that i make some mistakes. I'm trying to bind two ListBoxes

<ListBox Margin="8,12.07,0,8" SelectionChanged="lbApplications_SelectionChanged"
                 Grid.Row="1" x:Name="lbApplications" Width="267.914" HorizontalAlignment="Left" 
                 ItemsSource="{Binding Path=Applications, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
<ListBox Margin="275.914,12.07,8,8" DisplayMemberPath="Message" 
                 Grid.Row="1" x:Name="lbEvents" MouseDoubleClick="lbEvents_MouseDoubleClick"
                 ItemsSource="{Binding Path=Events, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />

Applications and Events are public properties in Window class.

I set DataContext to 'this' to both listboxes and implement INotifyPropertyChanged to 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 times. What am I doing wrong??

Thanks a lot for help.

A: 

The problem is that your property value hasnt changed.. its 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..

HTH

Arcturus
+1  A: 

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.

GreenReign
Thanks. It works, but only musst be set the listbox datacontext=this or ElementName=window in {Binding}.
Jan Remunda
Good point. I updated the answer.
GreenReign