C# 选中/取消选中列表项中复选框的WPF行为
我有一个应用程序,其中有几个项控件(TreeView和其他控件),其中包含一个包含复选框的项模板。此复选框选中状态绑定到项目视图模型的IsChecked属性。这在点击复选框时可以正常工作,但不可能用键盘选中/取消选中它们(我相信这是因为复选框本身永远不会得到焦点) 我喜欢DLeh在这里提出的解决方案:但我希望有一个改进:与其让行为在基本视图模型(包含项列表的vm)上调用命令,不如让行为直接作用于项的IsChecked属性。 我的问题是,我不知道如何修改行为或如何在其上设置绑定,以便该行为可以访问项的IsChecked属性。 因此,与以下内容不同:C# 选中/取消选中列表项中复选框的WPF行为,c#,wpf,checkbox,behavior,C#,Wpf,Checkbox,Behavior,我有一个应用程序,其中有几个项控件(TreeView和其他控件),其中包含一个包含复选框的项模板。此复选框选中状态绑定到项目视图模型的IsChecked属性。这在点击复选框时可以正常工作,但不可能用键盘选中/取消选中它们(我相信这是因为复选框本身永远不会得到焦点) 我喜欢DLeh在这里提出的解决方案:但我希望有一个改进:与其让行为在基本视图模型(包含项列表的vm)上调用命令,不如让行为直接作用于项的IsChecked属性。 我的问题是,我不知道如何修改行为或如何在其上设置绑定,以便该行为可以访问
<DataGrid>
<i:Interaction.Behaviors>
<shared:ToggleSelectOnSpace ToggleSelectCommand="{Binding Data.ToggleSelectParticipantCommand, Source={StaticResource BindingProxy}}" />
</i:Interaction.Behaviors>
...
</DataGrid>
更新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>
不是对问题本身的回答,但下面将说明列表项中的复选框可以接收键盘焦点 我使用默认的VisualStudio模板创建了一个新的WPF项目。这将创建一个名为“MainWindow”的窗口。下面是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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Windows;
命名空间WpfApplication1
{
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
Thingies=新列表
{
新事物{Name=“abc”,IsChecked=false},
新内容{Name=“def”,IsChecked=true},
新事物{Name=“ghi”,IsChecked=false},
新事物{Name=“jkl”,IsChecked=true},
新事物{Name=“mno”,IsChecked=false},
}.ToArray();
DataContext=this;
}
public Thingy[]Thingies{get;private set;}
公共类内容:InotifyProperty已更改
{
公共字符串名称{get;set;}
公共场所被检查
{
得到
{
返回-已检查;
}
设置
{
如果(_已检查!=值)
{
_isChecked=值;
if(PropertyChanged!=null)
{
财产变更(本,
新的房地产变更开发标记(“已检查”);
}
Console.WriteLine(名称+“=”+_已检查);
}
}
}
布尔被检查;
公共事件属性更改事件处理程序属性更改;
}
}
}
main window.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>
命令中的逻辑是什么样子的?请参阅question@Francesc我能够创建一个项目模板,其中有一个复选框
控件,可以接收焦点并使用空格键进行切换,所以我不确定为什么这对您不起作用。是否有其他东西阻止了键盘焦点,例如进一步设置元素树的属性?如果你愿意,我可以发布我的示例代码。@Steven,老实说,我不知道为什么它不起作用。我在问题中张贴了我的模板。没有什么特别的。我只是假设stackpanel正在吞噬空格键事件。“我很想看看你的解决方案。”弗兰切斯克贴出了一个答案,里面有我的示例代码。这可能有帮助,也可能没有帮助!你说得对。这也适用于我的项目,当我查看这一点时,我发现我的一个实例也适用。我正在调查为什么它在某些情况下不起作用,但我感觉有某种风格在起干扰作用,因为我可以在不起作用的情况下看到不同的“选定”视觉效果。非常感谢。我在错误的地方寻找解决方案。
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;
}
}
}
<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>