XAML - 如何拥有全局输入绑定?

发布于 2024-07-26 18:26:36 字数 1099 浏览 6 评论 0原文

我有一个带有多个窗口的 WPF 应用程序。 我想定义全局输入绑定。

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

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

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

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

编辑:在他的回答中 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”,因为它没有可访问的设置访问器。

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

有任何想法吗? 谢谢!

I have a WPF application with several windows. I would like to define GLOBAL inputBindings.

To define LOCAL inputbindings, i just declare the input in Window.InputBindings or UserControl.InputBindings.

To define GLOBALs, I wish i could do the same with the Application class...

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

If i have the same binding in 2 different windows, i have to code it twice. This doesn't meet D.R.Y.'s philosophy and i guess there is a better way...

EDIT : in his answer Kent Boogaart advices me to use Style. Unfortunately, i can't figure out how to define it. This is the code :

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

It raises an error : error MC3080: The Property Setter 'InputBindings' cannot be set because it does not have an accessible set accessor.

Is my style wrong?
Is there another solution?

Any ideas? thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离笑几人歌 2024-08-02 18:26:37

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

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!"); }
    }
}

One solution is to use an Attached Property with a Style to set the InputBindings on all the controls of a given type in your application. Unfortunately, since you can't make a "catch-all" Style (that I know of, anyway), you'll have to create a Style for each control type on which you want to set the InputBindings (this shouldn't, however, be too many controls). Below is some sample code that shows how to do this:

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!"); }
    }
}
凯凯我们等你回来 2024-08-02 18:26:37

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

You could create a Style that is applied to all your Windows. That Style could set the InputBindings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文