2012-02-15 3 views
1

WPFで2つのリストボックスを同期する際に問題が発生します。WPFでマスタ/ディテールリストボックスを同期できません

データセットを作成し、2つのDataTableを設定しました。 1つのDataTableはPeople用で、もう1つのDataTableは写真用です。

私は両方のListBoxを互いに独立して機能させることができますが、それらを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に詳細をバインドする必要があります。写真はPeopleのListプロパティです。 DataTablesではなくList/ObservableCollectionsに行く価値があります。 .NETコレクションには今や大きな力があります。アイテムを追加するために次元を変更しなければならなかった配列の時代になって、DataTableを使う時間が増えました。ああ、DataReaderでクラスを作成し、DataTableから抜け出す。 – Paparazzi

答えて

3

あなたのデータのより代表的であるのviewmodelを構築する必要があります。

ここに提案があります。 ページのDataContextになるMainViewModelクラスを作成します。 MainViewModelにはPeopleのObservableCollection < PersonViewModel>があります。 また、SelectedPersonプロパティを持ちます。SelectedPersonは、PeopleListのSelectedItemにバインドします。 各PersonViewModelには、その人物の写真のObservableCollection < PhotoViewModel>(名前、または他の人物のデータ)があります。

次に、あなたのXAMLは、より次のようになりますのSelectedItemはSelectedPersonプロパティにバインド2ウェイですので

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

あなたが最初のリストの中の人をクリックすると、第二のリストが自動的に更新されますその人の写真を示す

バインドするプロパティは、INotifyPropertyChangedを実装する必要があります。あなたはMVVM designパターンにいくつかの研究をしたいかもしれません。一度それに慣れると、WPFを実行する唯一の方法です。私はMVVM-lightをチェックアウトすることをお勧めします。それは必要ではありませんが、いくつかのビューモデルの設定を少し簡単にすることができます。

+0

今私は何かを調べている。ご協力いただきありがとうございます! – Haluska

+0

私はMVVM Lightを十分に推奨できません。素晴らしいです! – reggaeguitar

関連する問題