我有一个带有多个项目控件(树视图和其他)的应用程序,其中包含一个带有复选框的项目模板。此复选框选中状态绑定到项视图模型的IsChecked属性。单击复选框时这可以正常工作,但是用键盘检查/取消选中它们是不可能的(我相信这是因为复选框本身永远不会得到焦点)。
我喜欢DLeh在这里提出的解决方案:https://stackoverflow.com/a/24327765/352826但是我想要一个改进:不要让行为在基本视图模型上调用命令(包含项目列表的vm),希望行为直接作用于项目的IsChecked属性。 我的问题是我不知道如何修改行为或如何设置绑定,以便行为可以访问项目的IsChecked属性。 所以,而不是以下:
<DataGrid>
<i:Interaction.Behaviors>
<shared:ToggleSelectOnSpace ToggleSelectCommand="{Binding Data.ToggleSelectParticipantCommand, Source={StaticResource BindingProxy}}" />
</i:Interaction.Behaviors>
...
</DataGrid>
我会有这样的事情:
<DataGrid>
<i:Interaction.Behaviors>
<shared:ToggleSelectOnSpace ItemsIsSelectedProperty="{Binding IsChecked}" />
</i:Interaction.Behaviors>
...
</DataGrid>
更新 我应该补充一点,我当前的实现使用itemscontrol中的PreviewKeyUp事件和后面的代码实现。这种方法的问题在于我在许多代码后面都有这个代码,所以有很多重复。我的目标是通过行为取代它。
private void TreeView_OnPreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
var tree = (TreeView) sender;
var item = tree.SelectedItem as IsSelectedViewModelBase;
if (item != null)
{
item.IsSelected = !item.IsSelected;
e.Handled = true;
}
}
}
更新2 这是项目模板,当您按下选定项目的空格键时,不会选中复选框。
<DataTemplate DataType="{x:Type viewModels:ItemViewModel}" >
<StackPanel Orientation="Horizontal" >
<CheckBox Focusable="False" IsChecked="{Binding IsSelected}" VerticalAlignment="Center" />
<StackPanel Margin="2">
<TextBlock Text="{Binding Username}" FontWeight="Bold" />
<TextBlock Text="{Binding FullName}" />
</StackPanel>
</StackPanel>
</DataTemplate>
答案 0 :(得分:0)
不是问题本身的答案,但以下内容将说明列表项中的复选框可以接收键盘焦点。
我使用默认的Visual Studio模板创建了一个新的WPF项目。这将创建一个名为&#34; MainWindow&#34;的单个窗口。这是XAML的内容和该窗口的代码隐藏。
<强> MainWindow.xaml.cs 强>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Thingies = new List<Thingy>
{
new Thingy { Name = "abc", IsChecked = false },
new Thingy { Name = "def", IsChecked = true },
new Thingy { Name = "ghi", IsChecked = false },
new Thingy { Name = "jkl", IsChecked = true },
new Thingy { Name = "mno", IsChecked = false },
}.ToArray();
DataContext = this;
}
public Thingy[] Thingies { get; private set; }
public class Thingy : INotifyPropertyChanged
{
public string Name { get; set; }
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
if (_isChecked != value)
{
_isChecked = value;
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs("IsChecked"));
}
Console.WriteLine(Name + " = " + _isChecked);
}
}
}
bool _isChecked;
public event PropertyChangedEventHandler PropertyChanged;
}
}
}
<强> MainWindow.xaml 强>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<ListBox ItemsSource="{Binding Thingies}">
<ListBox.ItemTemplate>
<DataTemplate>
<UniformGrid Rows="1" Width="400">
<TextBlock Text="{Binding Name}" />
<CheckBox IsChecked="{Binding IsChecked}" />
</UniformGrid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>