Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 选中/取消选中列表项中复选框的WPF行为_C#_Wpf_Checkbox_Behavior - Fatal编程技术网

C# 选中/取消选中列表项中复选框的WPF行为

C# 选中/取消选中列表项中复选框的WPF行为,c#,wpf,checkbox,behavior,C#,Wpf,Checkbox,Behavior,我有一个应用程序,其中有几个项控件(TreeView和其他控件),其中包含一个包含复选框的项模板。此复选框选中状态绑定到项目视图模型的IsChecked属性。这在点击复选框时可以正常工作,但不可能用键盘选中/取消选中它们(我相信这是因为复选框本身永远不会得到焦点) 我喜欢DLeh在这里提出的解决方案:但我希望有一个改进:与其让行为在基本视图模型(包含项列表的vm)上调用命令,不如让行为直接作用于项的IsChecked属性。 我的问题是,我不知道如何修改行为或如何在其上设置绑定,以便该行为可以访问

我有一个应用程序,其中有几个项控件(TreeView和其他控件),其中包含一个包含复选框的项模板。此复选框选中状态绑定到项目视图模型的IsChecked属性。这在点击复选框时可以正常工作,但不可能用键盘选中/取消选中它们(我相信这是因为复选框本身永远不会得到焦点)

我喜欢DLeh在这里提出的解决方案:但我希望有一个改进:与其让行为在基本视图模型(包含项列表的vm)上调用命令,不如让行为直接作用于项的IsChecked属性。 我的问题是,我不知道如何修改行为或如何在其上设置绑定,以便该行为可以访问项的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>