MVVM を使用する場合、データと見なされるものと、厳密には UI と見なされるものに注意する必要があります。
SelectedItemsデータの一部になるのか、それとも UI だけになるのか?
それがデータの一部である場合はIsSelected、データ クラスを拡張してプロパティを含めるか、 と のみを含むラッパー クラスを作成することを意味する場合でも、データ モデルにプロパティがIsSelected必要です。を保持できるため、最初のオプションがおそらく好まれます。これにより、列のバインドがより簡単になります。bool IsSelectedobject MyDataItemAutoGenerateColumns="True"
次に、データ項目DataGridRow.SelectedItemのプロパティにバインドします。IsSelected
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
ただしSelectedItems、UI のみの場合、またはこのインスタンスで何らかの理由で MVVM パターンを壊している場合は、バインドされていないものを作成し、CheckBoxコード ビハインドを使用して、CheckBoxが に正しく同期されるようにすることができますSelectedItem。
簡単なサンプル アプリを作成しました。コードは次のようになります。
まず、. を使用してバインドされていないCheckBox列を列リストに追加しましたDataGridTemplateColumn。これはAutoGenerateColumns、列のリストの前に追加されます。
<DataGrid x:Name="TestDataGrid" ItemsSource="{Binding Test}"
SelectionMode="Extended" CanUserAddRows="False"
PreviewMouseLeftButtonDown="TestDataGrid_PreviewMouseLeftButtonDown_1">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="TestCheckBox"
PreviewMouseLeftButtonDown="CheckBox_PreviewMouseLeftButtonDown" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
次に、行のプロパティを設定するPreviewMouseDownイベントをに追加しました。CheckBoxIsSelected
private void CheckBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var chk = (CheckBox)sender;
var row = VisualTreeHelpers.FindAncestor<DataGridRow>(chk);
var newValue = !chk.IsChecked.GetValueOrDefault();
row.IsSelected = newValue;
chk.IsChecked = newValue;
// Mark event as handled so that the default
// DataGridPreviewMouseDown doesn't handle the event
e.Handled = true;
}
をナビゲートして、クリックしたものに関連付けられているVisualTreeを見つけて選択する必要があります。生活を楽にするために、ブログで を見つけるためにいくつかのカスタム VisualTreeHelper を使用しています。同じコードを使用することも、独自のメソッドを作成して を検索することもできます。DataGridRowCheckBoxDataGridRowVisualTree
そして最後に、ユーザーが 以外の場所をクリックした場合、デフォルトの選択イベントCheckBoxを無効にします。DataGridこれにより、IsSelectedをクリックしたときにのみ値が変更されるようになりますCheckBox。
さまざまなレベルで選択を無効にする方法は複数ありますが、簡単にするためにDataGrid.PreviewMouseLeftButtonDown、ユーザーが をクリックしなかった場合はイベントを無効にしましたCheckBox。
private void TestDataGrid_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
{
var chk = VisualTreeHelpers.FindAncestor<CheckBox>((DependencyObject)e.OriginalSource, "TestCheckBox");
if (chk == null)
e.Handled = true;
}
カスタムVisualTreeHelpersを再度使用してビジュアル ツリーをナビゲートし、CheckBox がクリックされたかどうかを確認し、ユーザーが 以外の場所をクリックした場合はイベントをキャンセルしますCheckBox。
または項目を追加CheckBoxする2 番目の要求については、これもまた、選択が UI の一部であるかデータの一部であるかによって異なります。SelectAllUnselectAll
UI の一部である場合は、 に を追加するだけで、CheckBoxクリックされDataGridTemplateColumn.HeaderTemplateたときに をループし、最初の列でDataGrid.Rowsを見つけて、CheckBoxオンまたはオフにします。
それがデータの一部である場合でも、同じことを行うことができます ( のDataGrid.Items代わりに にバインドされた値を設定するだけCheckBox.IsCheckedですDataGrid.Rows) 。ViewModel