I’m having some problems syncing two ListBoxes in WPF.
I’ve created and populated a DataSet with two DataTables. One DataTable is for People and the other DataTable is for their Photos.
I can get both ListBoxes to function independently of each other, but I want them to function as a Master to Detail.
This is my first WPF project so any suggestions are greatly appreciated!
C# CODE:
DataSet ds = new DataSet();
UserManagement.Users users = new UserManagement.Users(_cnFaces);
ds = users.GetUsersForFR();
users = null;
lbPeople.DataContext = ds;
lbPhotos.DataContext = ds;
public DataSet GetUsersForFR()
{
Library.DAL.DataCE helper;
try
{
string sSQLPeople = @"
SELECT
*
FROM
tblUsers
";
string sSQLPhotos = @"
SELECT
*
FROM
tblFacialRecognition
";
helper = new Library.DAL.DataCE(_cnFaces);
DataSet ds = new DataSet();
ds.Tables.Clear();
ds.Tables.Add(helper.GetDataTable(sSQLPeople, CommandType.Text, "People"));
ds.Tables.Add(helper.GetDataTable(sSQLPhotos, CommandType.Text, "Photos"));
DataRelation relation = new DataRelation("People2Photos",
ds.Tables["People"].Columns["fldUsername"],
ds.Tables["Photos"].Columns["fldUsername"]);
ds.Relations.Add(relation);
return ds;
}
finally
{
helper = null;
}
}
DATATEMPLATES:
<DataTemplate x:Key="PeopleTemplate">
<StackPanel Margin="3">
<DockPanel >
<Image Source="{Binding fldPrimaryPhoto}" />
</DockPanel>
<DockPanel>
<TextBlock Text="{Binding fldUsername}" Foreground="Black" FontWeight="Bold" />
</DockPanel>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="PhotoTemplate">
<StackPanel Margin="3">
<DockPanel >
<Image Source="{Binding fldPhoto}" />
</DockPanel>
<DockPanel>
<TextBlock Text="{Binding fldUsername}" Foreground="Black" FontWeight="Bold" />
</DockPanel>
</StackPanel>
</DataTemplate>
LISTBOXES:
<ListBox Name="lbPeople"
ItemsSource="{Binding Path=Tables[0]}"
IsSynchronizedWithCurrentItem="True"
ItemTemplate="{StaticResource PeopleTemplate}"
SelectionChanged="lbPeople_SelectionChanged" />
<ListBox Name="lbPhotos"
Margin="0,0,326,0"
ItemsSource="{Binding Path=Tables[1]}"
IsSynchronizedWithCurrentItem="True"
ItemTemplate="{StaticResource PhotoTemplate}" />
You should build a viewmodel that is more representative of your data.
Here is a suggestion:
Create a MainViewModel class, which will be the DataContext for your page.
MainViewModel will have an ObservableCollection< PersonViewModel > for the People.
Also, it will have a property SelectedPerson, which you will bind to the people list’s SelectedItem.
Each PersonViewModel will have an ObservableCollection< PhotoViewModel > for that person’s photos (and maybe a Name, or some other ‘person’ data).
Then, your xaml will look more like this:
Because SelectedItem is 2-way bound to SelectedPerson property, when you click a person in the first list, the second list will automatically update to show that person’s photos.
The properties that you bind to need to implement INotifyPropertyChanged. You might want to do some research into MVVM design pattern. Once you get used to it, it really is the only way to do WPF. I would recommend checking out MVVM-light; it is not necessary but can make some viewmodel setup a little easier.