I've been having some trouble getting a listbox to correctly bind to a collection.
I'll give the framework code, then explain what I want it to do.
XAML Markup:
<ListBox DataContext="{Binding Foos, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding Main.SelectedFoo, Mode=TwoWay,
Source={StaticResource Locator},
UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding Main.SelectedFoo, Source={StaticResource Locator}}"/>
<ListBox ItemsSource="{Binding Main.SelectedFoo.Bars}" SelectedItem="{Binding Main.SelectedBar}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Right">
<!-- The binding requires "{Binding .}" because a path must be explicitly set for Two-Way binding,
even though {Binding .} is supposed to be identical to {Binding} -->
<TextBox Text="{Binding Path=. , UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
C# ViewModel:
private ObservableCollection<Foo> _barList = new ObservableCollection<Foo>();
private const string BardListPN = "FooList";
public ObservableCollection<Foo> FooList
{
get { return _fooList; }
set
{
if (_fooList == value)
{
return;
}
var oldValue = _fooList;
_fooList = value;
RaisePropertyChanged(FooListPN);
}
}
private Foo _selectedFoo;
private const string SelectedFooPN = "SelectedFoo";
public Foo SelectedFoo
{
get { return _selectedFoo; }
set
{
if (_selectedFoo == value)
{
return;
}
var oldValue = _selectedFoo;
_selectedFoo = value;
// Update bindings, no broadcast
RaisePropertyChanged(SelectedFooPN);
}
}
public const string SelectedBarPN = "SelectedBar";
private string _selectedBar = "";
public string SelectedBar
{
get
{
return _selectedBar;
}
set
{
if (_selectedBar == value)
{
return;
}
var oldValue = _selectedBar;
_selectedBar = value;
// Update bindings, no broadcast
RaisePropertyChanged(SelectedBarPN);
}
}
C# Model:
public class Foo
{
public ICollection<string> Bars
{
get { return _bars; }
set
{
_bars= value;
NotifyPropertyChanged("Bars");
// snipped obvious INotifyPropertyChanged boilerplate code
}
}
}
My problem is that any changes to the textboxes for the strings in the Bar
collection aren't set. When the selected Foo
changes to a different Foo
and back, the original Bars
are displayed.
Could someone tell me what I'm doing wrong? This seems like it should be much more simple. Thanks!
Update: I've changed the code as per Tri Q's suggestion, but the changes made to the textbox aren't reflected in the property itself. Any ideas?