C# 选中/取消选中带有空格的复选框/在listview-wpf的gridview中输入
我有一个C# 选中/取消选中带有空格的复选框/在listview-wpf的gridview中输入,c#,wpf,xaml,gridview,C#,Wpf,Xaml,Gridview,我有一个GridView,其中CheckBox作为一列,TextBlock作为另一列。以下是XAML代码: <ListView.View> <GridView> <GridView.ColumnHeaderContainerStyle> <Style> <Setter Property="UIElement.Visibility"
GridView
,其中CheckBox
作为一列,TextBlock
作为另一列。以下是XAML
代码:
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style>
<Setter Property="UIElement.Visibility"
Value="Collapsed"/>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding}"
IsChecked="{Binding Path=IsFormChecked, Mode=TwoWay}"
IsEnabled="{Binding Path=IsUnRestricted}"
IsThreeState="False"
UIElement.KeyUp="CheckBox_KeyUp" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="600"
Tag="{Binding}"
IsEnabled="{Binding Path=IsUnRestricted}"
Text="{Binding Path=FormName}"
MouseUp="TextBlock_MouseUp">
<TextBlock.ToolTip>
<TextBlock Text="{Binding Path=FormName}"/>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
当我用键盘访问此
GridView
时,选择了完整的行(复选框
以及TextBlock
)。现在,如果我按空格键,什么也不会发生。如果我想用键盘访问复选框
,我必须再次按tab键,以便将焦点设置在复选框上,并且我可以使用空格键选中/取消选中它。我想做的是当焦点在我想选中/取消选中复选框的行上时,只需按空格键一次。如果您对当前选择的项目有绑定,您可以在列表视图上处理PreviewKeyUp
事件:
<ListView PreviewKeyUp="OnGridKeyUp"
SelectedItem="{Binding MySelectedItem}"
SelectionMode="Single"
ItemsSource="{Binding ItemsList}">
...
</ListView>
这显然要求您在代码背后拥有viewmodel的句柄。这可以很容易做到:
var vm = DataContext as MyViewModel;
这不是最具MVVM的方式,但嘿…我用了一种更为MVVM友好的方式来实现这一点:
步骤1:创建此行为
public class ToggleSelectOnSpace : Behavior<DataGrid>
{
public static readonly DependencyProperty toggleSelectCommand =
DependencyProperty.Register("ToggleSelectCommand",
typeof(ICommand),
typeof(ToggleSelectOnSpace));
public ICommand ToggleSelectCommand
{
get { return this.GetValue(toggleSelectCommand) as ICommand; }
set { this.SetValue(toggleSelectCommand, value); }
}
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.PreviewKeyUp += PreviewKeyUp;
}
protected override void OnDetaching()
{
this.AssociatedObject.PreviewKeyUp -= PreviewKeyUp;
base.OnDetaching();
}
private void PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
if (ToggleSelectCommand != null)
{
ToggleSelectCommand.Execute(this.AssociatedObject.SelectedItems);
}
}
}
}
public类切换selectonspace:Behavior
{
public static readonly dependencProperty toggleSelectCommand=
DependencyProperty.Register(“ToggleSelectCommand”,
类型(ICommand),
typeof(ToggleSelectOnSpace));
公共ICommand ToggleSelectCommand
{
get{将this.GetValue(toggleSelectCommand)返回为ICommand;}
设置{this.SetValue(toggleSelectCommand,value);}
}
受保护的覆盖无效附加()
{
base.onatached();
this.AssociatedObject.PreviewKeyUp+=PreviewKeyUp;
}
附加时受保护的覆盖无效()
{
this.AssociatedObject.PreviewKeyUp-=PreviewKeyUp;
base.OnDetaching();
}
private void PreviewKeyUp(对象发送方,KeyEventArgs e)
{
if(e.Key==Key.Space)
{
如果(ToggleSelectCommand!=null)
{
ToggleSelectCommand.Execute(this.AssociatedObject.SelectedItems);
}
}
}
}
步骤2:在视图模型中实现类似的命令(命令的方法逻辑)
private void切换选择参与者(对象选择对象)
{
var items=(System.Collections.IList)selectedObjects;
var collection=items.Cast().ToList();
bool selection=!collection.All(x=>x.IsSelected);
foreach(集合中的var项)
item.IsSelected=选择;
}
步骤3:将行为绑定到网格,并将命令绑定到行为
<DataGrid>
<i:Interaction.Behaviors>
<shared:ToggleSelectOnSpace ToggleSelectCommand="{Binding Data.ToggleSelectParticipantCommand, Source={StaticResource BindingProxy}}" />
</i:Interaction.Behaviors>
...
</DataGrid>
...
()嘿,我还没有使用MVVM到那种程度,但PreviewKeyUp事件解决了我的问题。谢谢……:)我认为这是一条路要走。我希望实现此解决方案,但我更希望能够绑定到单个项的IsSelected属性(该属性已存在并绑定到复选框),而不必添加命令。我的问题是,我不知道如何将项的属性绑定到行为的属性。你能建议怎么做吗?谢谢你也许应该更彻底地解释你的问题。好的,我已经为它创建了一个问题,试图尽我所能解释它:
private void ToggleSelectParticipant(object selectedObjects)
{
var items = (System.Collections.IList)selectedObjects;
var collection = items.Cast<MyItemType>().ToList();
bool selection = !collection.All(x => x.IsSelected);
foreach (var item in collection)
item.IsSelected = selection;
}
<DataGrid>
<i:Interaction.Behaviors>
<shared:ToggleSelectOnSpace ToggleSelectCommand="{Binding Data.ToggleSelectParticipantCommand, Source={StaticResource BindingProxy}}" />
</i:Interaction.Behaviors>
...
</DataGrid>