Master Detail Forms the WPFand Silverlight Way
Sometimes things are so easy that you just do not expect them to be that way. The problem is as old as databases and forms. You got an list and a detail form and you want to have it synchronized. There are a lot of solutions in the world to that problem, but there has never been one so easy like in WPF and Silverlight.
In my example I have two texboxes and a listbox. The listbox is showing a list of adresses and the texboxes are displaying name and city. The trick begins with my "dataclass". This one I call AdrLogic and it implements INotifyPropertyChanged. So it looks like that.
class AdrLogic: INotifyPropertyChanged
In my case I fetchted the data from a webservice, but that is another story.
public SilverLightServiceClient.AdrService.AdrServiceClient service = new SilverLightServiceClient.AdrService.AdrServiceClient();
For my data I use an
ObservableCollection.
public ObservableCollection <SilverLightServiceClient.AdrService.AdrData> AdressList
And I create an Index for my Collection and here goes the property change.
public int CurrentIndex
{
get { return currentindex; }
set
{
currentindex = Math.Min(value, AdressList != null ? AdressList.Count - 1 : -1);
OnPropertyChanged("CurrentIndex");
OnPropertyChanged("CurrentAdress");
}
}
private int currentindex = -1;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}So I got a list with an current Index where every change is reported as is the change of the current index pointer. All I have to do now is to connect the data and the index to my XAML.
<TextBox IsReadOnly="{Binding Path=IsEmpty}" Margin="12,12" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="120" Height="22" Text="{Binding Path=CurrentAdress.Name, Mode=TwoWay}" />
<TextBox IsReadOnly="{Binding Path=IsEmpty}" Margin="12,40" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="120" Height="22" Text="{Binding Path=CurrentAdress.City, Mode=TwoWay}" /><ListBox Margin="140,12" Width="200" Height="200" HorizontalAlignment="Left"
VerticalAlignment="Top" SelectedIndex="{Binding Path=CurrentIndex, Mode=TwoWay}"
ItemsSource="{Binding Path=AdressList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Name}" Margin="0,0,50,0" />
<TextBlock Text="{Binding City}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The TwoWay Binding is now doing all the synchronization for me. By binding the SelectedIndex to the CurrentIndex of the indexed Observable Collection, there is always the selected data in my detail form.