MVVM を使用する場合、データと見なされるものと、厳密には UI と見なされるものに注意する必要があります。
SelectedItems
データの一部になるのか、それとも UI だけになるのか?
それがデータの一部である場合はIsSelected
、データ クラスを拡張してプロパティを含めるか、 と のみを含むラッパー クラスを作成することを意味する場合でも、データ モデルにプロパティがIsSelected
必要です。を保持できるため、最初のオプションがおそらく好まれます。これにより、列のバインドがより簡単になります。bool IsSelected
object MyDataItem
AutoGenerateColumns="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
イベントをに追加しました。CheckBox
IsSelected
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 を使用しています。同じコードを使用することも、独自のメソッドを作成して を検索することもできます。DataGridRow
CheckBox
DataGridRow
VisualTree
そして最後に、ユーザーが 以外の場所をクリックした場合、デフォルトの選択イベント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 の一部であるかデータの一部であるかによって異なります。SelectAll
UnselectAll
UI の一部である場合は、 に を追加するだけで、CheckBox
クリックされDataGridTemplateColumn.HeaderTemplate
たときに をループし、最初の列でDataGrid.Rows
を見つけて、CheckBox
オンまたはオフにします。
それがデータの一部である場合でも、同じことを行うことができます ( のDataGrid.Items
代わりに にバインドされた値を設定するだけCheckBox.IsChecked
ですDataGrid.Rows
) 。ViewModel