【问题标题】:WPF CommandBinding NOT on the top level item/Window/thisWPF CommandBinding 不在顶级项目/窗口/此
【发布时间】:2011-03-06 09:27:15
【问题描述】:

我想要的只是不同选项卡上的不同绑定,因此切换选项卡会切换命令可用性。我认为 CommandBindings 就是这样工作的。

但我在尝试让这个简单的示例工作时花费了最后一段时间。要么我从根本上误解了(这不是第一次),要么出了点问题。

我将 CommandBinding 添加到 textBoxA 但未添加到 textBoxB。在它们之间移动应该启用和禁用设置为相应命令的按钮。

将 CommandBinding 添加到 Window 可以很好地启用按钮,但这会扼杀特定于项目的 CommandBindings 的全部意义。

使用此 XAML

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="500">
    <Canvas>
        <Button Canvas.Left="31" Canvas.Top="24" Content="Click Me" Name="button1" Width="100"/>
        <TextBox Canvas.Left="155" Canvas.Top="22" Height="23" Name="textBoxA" Width="120" Text="A" />
        <TextBox Canvas.Left="298" Canvas.Top="22" Height="23" Name="textBoxB" Width="120" Text="B" />
    </Canvas>
</Window>

在后面使用此代码

public MainWindow()
{
    InitializeComponent();

    button1.Command = ApplicationCommands.Open;

    var _Binding = new CommandBinding(button1.Command);
    textBoxA.CommandBindings.Add(_Binding);
    textBoxB.CommandBindings.Clear(); // nothing bound

    _Binding.CanExecute += (s, e) =>
    {
        e.CanExecute = true;
    };

    _Binding.Executed += (s, e) =>
    {
        MessageBox.Show("Hello");
    };
}

您会看到(如果您尝试使用此代码)该按钮仍然处于禁用状态,即使您从一个文本框移动到另一个文本框也是如此。 (即使 textBoxA 应该启用按钮,因为它实现了按钮的 CommandBinding)。

这应该如何工作?

提前谢谢你。

【问题讨论】:

标签: wpf icommand commandbinding


【解决方案1】:

我看不出这是如何工作的,您似乎错过了重点(抱歉)- CommandBindings 应该应用于父元素(将它放在画布上也可以)。单击按钮时,RoutedCommand 将通过可视化树“冒泡”,这意味着任何父元素都将触发绑定到该命令的事件。按钮保持禁用状态的原因是您此时无法执行打开命令,并且由于它不在执行路径中,因此未评估 CommandBinding。看这里:

http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.aspx

【讨论】:

  • 如果您看这里 (stackoverflow.com/questions/1375483/…),它表明 WPF 具有文本框(可能还有其他控件)的默认绑定。我也知道文本框默认复制/粘贴(例如)。不只是在类似父控件的控件上,例如画布。例如,如果文本框不能按照我的建议进行操作,为什么它会有一个 CommandBindings 集合属性。 (顺便说一句,谢谢您的回复)另外,设置为 Canvas(如果有两个)与我的示例有相同的问题。
  • 据我所知,CommandBinding 的目的是允许树上较高的元素在对较低的元素触发命令时侦听和执行。文本框具有 CommandBindings 属性,因为它们是 UIElement,您实际上可以毫无问题地将按钮放在文本框内,然后它会拾取按钮命令事件。
【解决方案2】:

我会试试看能不能达到你的场景:

<Canvas>
    <Button ... Command="Open">
        <CommandBindings>
            <CommandBinding Command="Open" Executed="OnOpen"/>
        <CommandBindings>
    </Button>
    <TextBox ... >
        <CommandBindings>
            <CommandBinding Command="Open" Executed="OnOpen"/>
        <CommandBindings>
    </TextBox>
    <TextBox ... />
</Canvas>

在代码隐藏中:

private void OnOpen(object sender, ExecutedRoutedEventArgs e)
{
    MessageBox.Show("Hello");
}

CommandBindings 的想法是作为一种快捷方式,让通用击键在上下文中的按钮和其他控件(通常是用户控件)中工作。然后每个区域对于 Open-command 可以有不同的含义(一个可能会打开一个文件 - 在另一个它将打开在 ListView 中选择的项目等等)。

在我的示例中 - 在 TextBox A 或按钮具有焦点时按 CTRL+O 将触发“Hello”消息框。但请阅读 Leom 链接到的页面以获得更深入的解释。

【讨论】:

  • 谢谢。所以,我的后续问题是我想使用 Open Command,但是当我在 TextBoxA 中时我想要一个 CommandBinding(比如 OnOpen1()),而当我在 TextBoxB 中时我想要一个不同的 CommandBinding(比如 OnOpen2())。而且,为了更好地衡量,如果我在 TextBoxC 中,我希望禁用该按钮。像您这样的直接实现可以正常工作。我意识到这一点。
  • 然后您只需交换有问题的 CommandBinding 的 Execute 部分。因此,一个用于 TextBoxA 的事件处理程序和另一个用于 TextBoxB 的事件处理程序。但是,您应该删除按钮的命令绑定 - 然后它应该全部工作,因为它将响应从逻辑焦点在 VisualTree 中“最近”的命令绑定 - (如果您在 TextBoxA 和 TextBoxB 中,则为 TextBoxA 的命令绑定,如果您在那里并且等等)。
【解决方案3】:

MSFT 在他们的 WPF 论坛中给了我正确的答案,这里是 http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bb3d1eb1-96fa-4fbc-beda-799613acb9f7

【讨论】:

    猜你喜欢
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 2019-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多