【问题标题】:XAML - How to have global inputBindings?XAML - 如何拥有全局 inputBindings?
【发布时间】:2010-11-09 10:17:53
【问题描述】:

我有一个带有多个窗口的 WPF 应用程序。我想定义 GLOBAL inputBindings。

要定义本地输入绑定,我只需在 Window.InputBindings 或 UserControl.InputBindings 中声明输入。

要定义 GLOBAL,我希望我可以对 Application 类做同样的事情......

<Application
....>
<Application.InputBindings>
...
</Application.InputBindings>

如果我在 2 个不同的窗口中有相同的绑定,我必须编码两次。这不符合 D.R.Y. 的理念,我想还有更好的方法......

编辑:在他的回答中 Kent Boogaart 建议我使用 Style。不幸的是,我不知道如何定义它。这是代码:

 <Application.Resources>
    <Style TargetType="Window">
        <Setter Property="InputBindings">
            <Setter.Value>
                <Window.InputBindings>
                    <KeyBinding KeyGesture="Ctrl+M" Command="local:App.MsgCommand />
                </Window.InputBindings>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources> 

它引发错误:错误 MC3080:无法设置属性设置器“InputBindings”,因为它没有可访问的设置访问器。

我的风格不对吗? 还有其他解决方案吗?

有什么想法吗?谢谢!

【问题讨论】:

    标签: wpf xaml inputbinding


    【解决方案1】:

    一种解决方案是使用Attached PropertyStyle 在应用程序中给定类型的所有控件上设置InputBindings。不幸的是,由于您无法创建“包罗万象”的Style(无论如何我都知道),因此您必须为要设置InputBindings 的每个控件类型创建一个Style (但是,这不应该是太多的控件)。下面是一些示例代码,展示了如何执行此操作:

    using System.Windows;
    using System.Windows.Input;
    
    namespace WpfApplication1
    {
        public class MyAttached
        {
            public static readonly DependencyProperty InputBindingsProperty =
                DependencyProperty.RegisterAttached("InputBindings", typeof(InputBindingCollection), typeof(MyAttached),
                new FrameworkPropertyMetadata(new InputBindingCollection(),
                (sender, e) =>
                {
                    var element = sender as UIElement;
                    if (element == null) return;
                    element.InputBindings.Clear();
                    element.InputBindings.AddRange((InputBindingCollection)e.NewValue);
                }));
    
            public static InputBindingCollection GetInputBindings(UIElement element)
            {
                return (InputBindingCollection)element.GetValue(InputBindingsProperty);
            }
    
            public static void SetInputBindings(UIElement element, InputBindingCollection inputBindings)
            {
                element.SetValue(InputBindingsProperty, inputBindings);
            }
    
        }
    }
    

    <Application x:Class="WpfApplication1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:loc="clr-namespace:WpfApplication1"
        StartupUri="Window1.xaml">
        <Application.Resources>
            <Style TargetType="TextBox">
                <Setter Property="loc:MyAttached.InputBindings">
                    <Setter.Value>
                        <InputBindingCollection>
                            <KeyBinding Key="A" Modifiers="Ctrl" Command="loc:Window1.MyAction" />
                        </InputBindingCollection>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style TargetType="Button">
                <Setter Property="loc:MyAttached.InputBindings">
                    <Setter.Value>
                        <InputBindingCollection>
                            <KeyBinding Key="A" Modifiers="Ctrl" Command="loc:Window1.MyAction" />
                        </InputBindingCollection>
                    </Setter.Value>
                </Setter>
            </Style>
        </Application.Resources>
    </Application>
    

    <Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:loc="clr-namespace:WpfApplication1"
        Title="Window1" Height="300" Width="300">
        <Window.CommandBindings>
            <CommandBinding Command="loc:Window1.MyAction" Executed="MyAction_Executed" />
        </Window.CommandBindings>
        <StackPanel>
            <Button Content="Try Ctrl+A Here!" />
            <TextBox Text="Try Ctrl+A Here!" />
        </StackPanel>
    </Window>
    

    using System.Windows;
    using System.Windows.Input;
    
    namespace WpfApplication1
    {
        public partial class Window1
        {
            public static readonly RoutedUICommand MyAction = new RoutedUICommand("MyAction", "MyAction", typeof(Window1));
    
            public Window1() { InitializeComponent(); }
    
            private void MyAction_Executed(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("MyAction!"); }
        }
    }
    

    【讨论】:

    • 当心 - 我在使用上面的代码时遇到了一些非常奇怪的问题。在我将它应用到一种样式之前它工作得很好,然后在随机情况下它似乎可以工作,但 DataContext 将为空(因此没有任何命令会绑定)。我不明白为什么这会随机发生。
    【解决方案2】:

    您可以创建一个Style 应用于您的所有Windows。 Style 可以设置InputBindings

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      • 1970-01-01
      • 2010-11-05
      • 2016-10-25
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多