用于检查/取消选中列表项中的复选框的WPF行为

时间:2015-02-11 15:01:08

标签: c# wpf checkbox behavior

我有一个带有多个项目控件(树视图和其他)的应用程序,其中包含一个带有复选框的项目模板。此复选框选中状态绑定到项视图模型的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>

1 个答案:

答案 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>