views:

173

answers:

3

Hi,

I am having a custom canvas derived from Canvas. It contains few ApplicationCommands like New/Open/Save etc. added like this -

this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New, New_Executed, 
New_Enabled));

New_Enabled always returns true.

This control is used in a wpf project having a menu bar; New/Open/Save menu button's are present in this menu bar with their Command set to respective ApplicationCommand like this -

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

Command works correctly when focus is present on Canvas but as soon as focus shifts to other control New button gets disabled. I have tried setting CommandTarget to main window but that too doesn't work.

Why this is happening and how can to make sure that New will always be enabled.

A: 

Check what New_Enabled does. That is the method that determines if the control is enabled or not.

Wallstreet Programmer
As I had mentioned in the question -'New_Enabled always returns true'
akjoshi
Could you try with a regular WPF button and menu to make sure that it's not the syncfusion controls causes it to disable when not in focus.
Wallstreet Programmer
A: 

The problem is that once your button and canvas share logical focus scope somewhere above in the hierarchy (most likely it is your window) the commands initiated in some menu never reach your canvas.

If you have just one canvas which you want to receive all your commands, just bind CommandTarget of your buttons to canvas:

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

Note that ICommand is marked with TypeConverterAttribute which converts strings like "New" to ApplicationCommands.New so you don't have to use x:Static markup extension.

You can do it in one place with Style for all buttons on the level your menu/toolbar.

However, if you have multiple canvases and want your command to be directed towards currently focused one, you have to do two things:

  1. make sure your canvas (or a control on it) has Focusable="True"
  2. limit the logical focus scope of your toolbar (or whatever container you use for your buttons) by setting FocusManager.IsFocusScope="True" on it. Some containers, like Menu, or ToolBar have that on by default. This way once command routing algorithm reaches the scope it will redirect it to the element currently having the keyboard focus.
repka
A: 

@repka - Thanks for your response; I had already tried using canvas name as CommandTarget but it doesn't work; Buttons gets enabled only when focus is on canvas as soon as i Click on some other control in window they gets disabled. I also tried using IsFocusScope but same result. Thanks for the command name strings tip.

I had to settle with this workaround, although I am not too happy with this -

    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));
    }
akjoshi