2012-02-15 58 views
1

我在同步WPF中的兩個ListBox時遇到了一些問題。我無法同步WPF中的主/明細列表框

我用兩個DataTable創建並填充了一個DataSet。一個DataTable用於People,另一個DataTable用於他們的照片。

我可以讓兩個ListBoxes彼此獨立運作,但我希望它們可以作爲Master to Detail來使用。

這是我的第一個WPF項目,所以任何建議,非常感謝!

C#代碼:

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> 

列表框:

<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}" /> 
+0

我不知道如何做到這一點的DataTables。對象需要將細節綁定到元素lbPeople SelectedItem。照片將成爲人物的List屬性。值得去List/ObservableCollections而不是DataTables。 .NET集合現在擁有如此強大的力量。在數組的日子裏,你不得不重新添加一個項目,有更多的時間使用DataTables。哦,並用DataReader填充你的類,並擺脫DataTables。 – Paparazzi 2012-02-15 01:32:13

回答

3

你應該建立一個視圖模型更能代表您的數據。

這是一個建議: 創建一個MainViewModel類,它將成爲您的頁面的DataContext。 MainViewModel將爲People創建一個ObservableCollection < PersonViewModel>。 此外,它將有一個屬性SelectedPerson,您將綁定到人員列表的SelectedItem。 每個PersonViewModel都有一個ObservableCollection < PhotoViewModel>用於該人的照片(也可能是一個姓名或其他「人物」數據)。

然後,XAML中看起來更像是這樣的:

<ListBox Name="lbPeople" 
     ItemsSource="{Binding People}" 
     IsSynchronizedWithCurrentItem="True" 
     ItemTemplate="{StaticResource PeopleTemplate}" 
     SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"/> 
<ListBox Name="lbPhotos" 
     Margin="0,0,326,0" 
     ItemsSource="{Binding SelectedPerson.Photos}" 
     IsSynchronizedWithCurrentItem="True" 
     ItemTemplate="{StaticResource PhotoTemplate}" /> 

因爲的SelectedItem是當你在第一個列表中單擊一個人必然SelectedPerson財產,2路,第二個列表會自動更新顯示那個人的照片

您綁定的屬性需要實現INotifyPropertyChanged。您可能需要對MVVM design模式進行一些研究。一旦你習慣了它,它確實是做WPF的唯一方法。我會建議檢查MVVM-light;這是沒有必要的,但可以使一些viewmodel設置更容易一些。

+0

現在我有一些東西要看。謝謝你的幫助! – Haluska 2012-02-15 07:45:45

+0

我不能推薦MVVM Light夠了,太棒了! – reggaeguitar 2014-06-06 17:29:58