使用带有Canvas的WPF命令不起作用

时间:2010-05-27 11:13:56

标签: wpf xaml canvas command commandbinding

我有一个源自Canvas的自定义画布。其中包含的ApplicationCommands / New / OpenSave / this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New, New_Executed, New_Enabled)); / {{}}等内容很少{/ p>}

New_Enabled

Command始终返回true。

此控件用于具有菜单栏的wpf项目;此菜单栏中显示新/打开/保存菜单按钮,ApplicationCommand设置为相应的<syncfusion:SimpleMenuButton x:Name="NewMenu" Icon="Images\New_Large.png" Label="New" IsEnabled="True" Command="{x:Static ApplicationCommands.New}" syncfusion:Ribbon.KeyTip="N"> </syncfusion:SimpleMenuButton> -

Canvas

命令在CommandTarget上存在焦点时正常工作,但只要焦点转移到其他控件,“新建”按钮就会被禁用。我已经尝试将{{1}}设置为主窗口,但这也不起作用。

为什么会发生这种情况以及如何确保始终启用“新建菜单”按钮?

2 个答案:

答案 0 :(得分:1)

问题是,一旦你的按钮和画布在层次结构中的某个位置共享逻辑焦点范围(很可能是你的窗口),在某些菜单中启动的命令永远不会到达你的画布。

如果您只有一个要接收所有命令的画布,只需将按钮的CommandTarget绑定到画布:

...
Command="New"
CommandTarget="{Binding ElementName=TheCanvas}"
...

请注意,ICommand标有TypeConverterAttribute,可将“新”等字符串转换为ApplicationCommands.New,因此您无需使用x:Static标记扩展名。

您可以使用Style在一个位置对菜单/工具栏上的所有按钮执行此操作。

但是,如果您有多个画布并希望将命令指向当前关注的画布,则必须做两件事:

  1. 确保您的画布(或其上的控件)具有Focusable="True"
  2. 通过在其上设置FocusManager.IsFocusScope="True"来限制工具栏(或用于按钮的任何容器)的逻辑焦点范围。某些容器(如“菜单”或ToolBar默认情况下启用该容器。这样,一旦命令路由算法到达范围,它就会将其重定向到当前具有键盘焦点的元素。

答案 1 :(得分:0)

@repka - 感谢您的回复;我已经尝试使用画布名称CommandTarget,但它不起作用;只有在焦点位于画布上时,按钮才会启用。单击窗口中的某些其他控件后,它们将被禁用。我也尝试使用IsFocusScope但结果相同。感谢命令名字符串提示。

我不得不解决这个问题,虽然我对此并不满意 -

    public WindowMain()
    {
        InitializeComponent();

        //Add commnad bindings
        //Need to do this to keep New/Open/Save/Run buttons always enabled
        //ToDo:[AJ] Look for better solution then this
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New, this.TheCanvas.New_Executed, this.TheCanvas.New_Enabled));
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, this.TheCanvas.Open_Executed, this.TheCanvas.Open_Enabled));
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save, this.TheCanvas.Save_Executed, this.TheCanvas.Save_Enabled));
        this.CommandBindings.Add(new CommandBinding(RTDesignerCanvas.Run, this.TheCanvas.Run_Executed));
    }