WPF KeyBinding命令不在自定义控件中触发

时间:2017-02-25 21:05:42

标签: c# wpf xaml mvvm custom-controls

我正在构建一个WPF自定义控件(注意:用户控件)。控件的c#代码定义如下:

using System.Windows;
using System.Windows.Controls;
using MvvmFoundation.Wpf;

namespace TextBoxWithInputBinding
{
    public class AutoComp : Control
    {
        static AutoComp()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(AutoComp), new FrameworkPropertyMetadata(typeof(AutoComp)));
        }

        public AutoComp()
        {
            DownCommand = new RelayCommand(() =>
            {
                System.Diagnostics.Debug.WriteLine("Down");
            });
            PressedCommand = new RelayCommand(() =>
            {
                System.Diagnostics.Debug.WriteLine("Pressed");
            });
        }

        public RelayCommand DownCommand
        {
            get { return (RelayCommand)GetValue(DownCommandProperty); }
            set { SetValue(DownCommandProperty, value); }
        }

        public static readonly DependencyProperty DownCommandProperty =
            DependencyProperty.Register("DownCommand", typeof(RelayCommand), typeof(AutoComp), new PropertyMetadata(null));

        public RelayCommand PressedCommand
        {
            get { return (RelayCommand)GetValue(PressedCommandProperty); }
            set { SetValue(PressedCommandProperty, value); }
        }

        public static readonly DependencyProperty PressedCommandProperty =
            DependencyProperty.Register("PressedCommand", typeof(RelayCommand), typeof(AutoComp), new PropertyMetadata(null));
    }
}

我在Generic.xaml中为控件定义模板,如下所示:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TextBoxWithInputBinding">
    <Style TargetType="{x:Type local:AutoComp}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:AutoComp}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            >
                        <StackPanel>
                            <TextBox>
                                <TextBox.InputBindings>
                                    <KeyBinding Key="Down" Command="{TemplateBinding DownCommand}"/>
                                </TextBox.InputBindings>
                            </TextBox>
                            <Button Content="Press me" Command="{TemplateBinding PressedCommand}"/>
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

当我按下&#34;按我&#34;按钮PressedCommand被触发(单词&#34; Pressed&#34;出现在输出窗口中 - 但是,当我输入TextBox并按下向下键时,没有任何反应。

我需要做什么才能使DownCommand发火?

2 个答案:

答案 0 :(得分:1)

如您所知,您应该使用通常的绑定标记替换TemplateBinding并使用{RelativeSource TemplatedParent}

<KeyBinding Key="Down"
    Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DownCommand}"/>
  

我仍然想知道为什么Button绑定与TemplateBinding配合使用但TextBox KeyBinding不支持?

因为TemplateBinding已经过优化,并且与使用普通Binding相比有一些限制。例如,它只能直接在ControlTemplates的可视树中使用,而不能在DataTriggerKeyBinding中使用。

您可以在此处找到有关此内容的更多信息:

WPF TemplateBinding vs RelativeSource TemplatedParent

答案 1 :(得分:0)

所以我找到了答案:我需要定期绑定而不是TemplateBinding:我替换了

<KeyBinding Key="Down" Command="{TemplateBinding DownCommand}"/>

<KeyBinding Key="Down"
    Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DownCommand}"/>

我仍然想知道为什么Button绑定适用于TemplateBinding,但TextBox KeyBinding却没有!!!