WPF:"ApplicationCommands.New";在MenuItem的情况下显示不正确的Source [英] WPF: "ApplicationCommands.New" showing incorrect Source in case of MenuItem

查看:139
本文介绍了WPF:"ApplicationCommands.New";在MenuItem的情况下显示不正确的Source的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是WPF的新手,正在学习.net 4.5中的Professional WPF示例.在命令一章中,有一个示例,其中多个控件可以发送同一命令.我正在使用Button,CheckBox和MenuItem来触发New命令.

I am new to WPF and am going through the examples of Professional WPF in .net 4.5. In the commands chapter, there is an example where multiple controls can send the same command. I am using a Button, CheckBox and MenuItem to trigger the New command.

我面临的问题是,如果第一次按下MenuItem,源将正确显示.但是,在单击按钮"或复选框"之后,再单击菜单项",将向我显示最后一个控件按钮"或复选框"的来源,以所按的为准.我找不到我的代码有什么问题,或者为什么WPF中的MenuItem会显示此行为.

The issue I am facing is that if MenuItem is pressed for the first time, the source shows correctly. However, after clicking the Button or CheckBox, then clicking MenuItem shows me the source of the last control Button or CheckBox, whichever was pressed. I couldn't find what was wrong with my code or why is this behavior shown by MenuItem in WPF.

下面是代码.

<Window x:Class="WpfApplication1.CommandSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="CommandSample" Height="300" Width="300">
  <Window.CommandBindings>
    <CommandBinding Command="New" Executed="CommandBinding_Executed" />
  </Window.CommandBindings>
  <StackPanel>
    <Button Command="New" MaxWidth="80" MaxHeight="30" Content="{x:Static ApplicationCommands.New}" />
    <Menu MaxHeight="30" VerticalAlignment="Top">
      <MenuItem Header="File">
        <MenuItem Command="New"></MenuItem>
      </MenuItem>
    </Menu>
    <CheckBox Command="New"></CheckBox>

  </StackPanel>
</Window>

namespace WpfApplication1 {
  public partial class CommandSample: Window {
    public CommandSample() {
      InitializeComponent();
    }
    private void CommandBinding_Executed(object sender,ExecutedRoutedEventArgs e)
    {
      MessageBox.Show("New Command launched by " + e.Source);
    }
  }
}

推荐答案

是的,这是正确的(或者至少是这样设计的).路由命令根据您指定的CommandTarget开始路由.如果未指定,则引发事件的对象通常将其自身用作起点(因此,在这种情况下为MenuItem).因此,如您所料,在这种情况下,路由以MenuItem开始.那里什么也没有处理,所以CommandManager沿父链向上移动.当它碰到一个名为FocusScope的元素(如Menu)时,它会检查父" FocusScope的FocusedElement(例如Menu父级的FocusScope,在这种情况下为Window).如果有一个FocusedElement(一旦将焦点集中在窗口的焦点范围内,例如按钮,复选框,可能放置在该堆栈面板中的文本框等,就会有一个),那么CommandManager将从以下位置开始路由事件该元素.完成此操作后,它将创建一个新的ExecutedRoutedEventArgs,其中OriginalSource是该起始元素(因此是按钮,复选框,文本框),然后继续沿树路由.

Yes this is correct (or at least that's how it's designed). Routed commands start routing based on the CommandTarget you specify. If one isn't specified typically the object raising the event uses itself as the starting point (so the MenuItem in this case). So the routing starts with the MenuItem in this case as you might expect. Nothing handles it there so the CommandManager goes up the parent chain. When it hits an element that is a FocusScope (like the Menu), it checks the FocusedElement of the "parent" FocusScope (e.g. the FocusScope of the parent of the Menu which in this case is the Window). If there is a FocusedElement (which there will be one once you have focused an element in the window's focus scope such as your button, checkbox, a textbox that you might put in that stackpanel, etc.) then the CommandManager starts routing the event from that element. When it does that it creates a new ExecutedRoutedEventArgs where the OriginalSource is that starting element (so the button, checkbox, textbox) and then continues routing up the tree.

因此,当您第一次运行该应用程序时,Window的FocusedElement(在您的示例中是根焦点范围)为null,因此不需要重新路由,因此CommandManager一直保持父链经过Menu和这就是为什么MenuItem出现为Source& OriginalSource.当您单击Button时,您将键盘焦点赋予其一部分,并且键盘焦点也成为其焦点范围的逻辑焦点元素(即,其包含FocusScope的FocusedElement).因此,当随后单击MenuItem并且CommandManager最终到达菜单时,它将重新路由到Button(或您在窗口的聚焦范围内聚焦的任何对象),并从那里开始路由.我说这是预料之中的,因为使用路由命令时,您希望路由通过逻辑上集中的元素,例如,菜单项的剪切"命令将触发具有焦点的窗口"中的文本框"的剪切.

So when you first ran the app, the FocusedElement of the Window (that's the root focus scope in your example) is null so there is no re-routing needed so the CommandManager just kept going up the parent chain past the Menu and that is why MenuItem appeared as the Source & OriginalSource. When you clicked on the Button you gave that keyboard focus and as part of it also became the logically focused element of its focus scope (i.e. the FocusedElement of its containing FocusScope). So when the MenuItem was subsequently clicked and the CommandManager ultimately reached the Menu, it then re-routed over to the Button (or whatever you focused in the window's focusscope) and started routing up from there. I say this is expected because with routed command you want the routing to go through the logically focused element so that for example, the Cut command of a menu item would trigger a cut of the TextBox in the Window that had focus.

这篇关于WPF:"ApplicationCommands.New";在MenuItem的情况下显示不正确的Source的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆