我有一个包含“IsChecked”属性的视图模型。此属性绑定到DataGrid RowHeaderTemplate。
我希望能够按住shift + ctrl键盘修饰符以允许更新多个复选框值。
例如:如果您选中第一行中的复选框,请按住shift键,然后选中第5行中的复选框;然后,行1-5将有一个选中的复选框。
以下是行标题模板:
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<CheckBox VerticalAlignment="Center"
VerticalContentAlignment="Center"
IsChecked="{Binding IsChecked}" />
</DataTemplate>
</DataGrid.RowHeaderTemplate>
我尝试了几种捕获PreviewMouseLeftButtonDown和KeyPress事件的组合,但我不确定绑定属性是否可行。
答案 0 :(得分:2)
我通过收听改变了IsChecked属性来提出解决方案。这可以满足我的需求。
private void OnItemOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
ItemViewModel newCheckedItem = sender as ItemViewModel;
int newCheckedItemIndex = _items.IndexOf(newCheckedItem);
if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && newCheckedItemIndex != _lastCheckedItemIndex)
{
int start = Math.Min(_lastCheckedItemIndex, newCheckedItemIndex);
int end = Math.Max(_lastCheckedItemIndex, newCheckedItemIndex);
int countToTake = end - start;
var itemsToCheck = _items.Skip(start).Take(countToTake).ToList();
foreach (ItemViewModel itemToCheck in itemsToCheck)
{
// Unhook the property changed event so we don't enter this method again
itemToCheck.PropertyChanged -= OnItemOnPropertyChanged;
itemToCheck.IsChecked = true;
// Re-register the proeprty changed event so that if we're unchecked/re-checked, we can respond.
itemToCheck.PropertyChanged += OnItemOnPropertyChanged;
}
_lastCheckedItemIndex = -1;
}
else
{
_lastCheckedItemIndex = newCheckedItemIndex;
}
}
}
答案 1 :(得分:0)
我遇到了同样的问题并且实现了与Michael G所呈现的类似的解决方案,但更直接。坦率地说,我无法使OnPropertyChanged
事件正常工作,所以我开发了以下解决方案:
XAML:
<DataGrid x:Name="_dg_DatasZones" Grid.Row="4" ItemsSource="{Binding}" LoadingRow="_dg_DatasZones_LoadingRow" Style="{StaticResource StandardGrid}" IsReadOnly="False"
SelectionMode="Single" >
<DataGrid.Columns>
<DataGridTemplateColumn CommonClasses:DataGridTemplateColumnStyleExtensions.Style="{StaticResource DataGridColumnIcon}">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Name="_CheckBox_SelectAllZone" Click="_CheckBox_SelectAllZone_Click" />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" Checked="Zone_Checked" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Foreground="Black" Width="50" Binding="{Binding Id}" ElementStyle="{StaticResource DataGridTextStyle}" Header="ID" HeaderTemplate="{StaticResource DataGridHeaderStyle}" IsReadOnly="True" />
<DataGridTextColumn Foreground="Black" MinWidth="100" Binding="{Binding Name}" ElementStyle="{StaticResource DataGridTextStyle}" Header="ZoneName" HeaderTemplate="{StaticResource DataGridHeaderStyle}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
确保SelectionMode="Single"
C#代码:
int _lastSelectedZoneIndex = -1;
private void Zone_Checked(object sender, RoutedEventArgs e)
{
int index = _dg_DatasZones.SelectedIndex;
if ( (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
&& index != _lastSelectedZoneIndex && _lastSelectedZoneIndex >= 0)
{
CheckBox chbx = (CheckBox)sender;
ListCollectionView view = _dg_DatasZones.DataContext as ListCollectionView;
if (view == null)
return;
int startindex = Math.Min(_lastSelectedZoneIndex, index);
int endindex = Math.Max(_lastSelectedZoneIndex, index);
for (int i = startindex; i < endindex; i++)
(view.GetItemAt(i) as TaskZoneData).IsChecked = (chbx.IsChecked == true);
}
else
{
_lastSelectedZoneIndex = index;
}
e.Handled = true;
}
目前这只适用于选择辩护,但不能取消选择。 要选择,您应该检查开始行(复选框)然后按Shift并检查结束行 - 并且将选择整个diapason。