Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
CommandRouting using a button.
Message
From
11/04/2008 13:09:49
 
 
General information
Forum:
ASP.NET
Category:
Windows Presentation Foundation (WPF)
Miscellaneous
Thread ID:
01309791
Message ID:
01309983
Views:
15
>>Thought I'd post this just in case someone else comes across this problem:
>>
>><Button Command="ApplicationCommands.Save">Apply</Button>
>>
>>This works as expected if the button is on a toolbar or the command is on a menu item.
>>But if it's just a button on a form the command binding:
>>
>>CommandBinding SaveCmdBinding = new CommandBinding(ApplicationCommands.Save,
>>                                                   SaveCmdExecuted,
>>                                                   SaveCmdCanExecute);
>>CommandBindings.Add(SaveCmdBinding);
>>
>>Only appears to walk the visual tree of the button and not the visual tree of the item with focus. Setting Focusable="False" on the button doesn't fix this :(
>
>Hi,
>I tried testing this. AFAICS the button, whether in a toolbar or on the form, gets focus before the commands are handled - i.e. no difference in behaviour.
>
>>So the command needs to be bound to a parent of the button.
>Again it seems to work the same for me whether I add the binding to the button or the form.
>
>Or am I misunderstanding your post?
>Regards,
>Viv

Here's the demo code I wrote to figure this out:

WPF Project - WpfCommandBinding
Window1.Xaml
<Window x:Class="WpfCommandBinding.Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:WpfCommandBinding" 
   Title="Window1" Height="300" Width="300">
   <DockPanel>
      <Menu DockPanel.Dock="Top" >
        <MenuItem Header="Save" Command="ApplicationCommands.Save"></MenuItem>
      </Menu>
    <ToolBar DockPanel.Dock="Top" Height="25" >
    <Button DockPanel.Dock="Bottom" Height="25" Command="ApplicationCommands.Save">Save</Button>
    </ToolBar>
    <Button DockPanel.Dock="Bottom" Height="25" Command="ApplicationCommands.Save">Save</Button>
    <local:UserControl1 x:Name="userControl">
    </local:UserControl1>
  </DockPanel>
</Window>
Window1.Xaml.cs
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

namespace WpfCommandBinding
  {
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window
    {
    public Window1()
      {
      InitializeComponent();
      this.userControl.textBox1.Focus();

      CommandBinding SaveCmdBinding = new CommandBinding(ApplicationCommands.Save,
                                                         SaveCmdExecuted,
                                                         SaveCmdCanExecute);
      // Never Works for the button :(
      //CommandManager.RegisterClassCommandBinding(typeof(UserControl1), SaveCmdBinding);

      // Never Works for the button :(
      userControl.CommandBindings.Add(SaveCmdBinding);

      // Works for Everything 
      //this.CommandBindings.Add(SaveCmdBinding);

      // Has no effect.
      //CommandManager.InvalidateRequerySuggested();
      }

    public void SaveCmdExecuted(object target, ExecutedRoutedEventArgs e)
      {
      String command, targetobj;
      command = ((RoutedCommand)e.Command).Name;
      targetobj = ((FrameworkElement)target).Name;
      MessageBox.Show("The " + command + " command has been invoked on target object " + targetobj);
      }

    public void SaveCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
      {
      Debug.WriteLine("SaveCmdCanExecute "+DateTime.Now.ToString());
      e.CanExecute = true;
      }
    }
  }
UserControl1.Xaml
<UserControl x:Class="WpfCommandBinding.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="92" Width="216">
    <Grid>
    <TextBox Margin="33,32,65,37" Name="textBox1" />
    <Button Height="23" Margin="33,0,108,6" Name="button1" Click="button1_Click" VerticalAlignment="Bottom">Button</Button>
  </Grid>
</UserControl>
UserControl1.Xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfCommandBinding
  {
  /// <summary>
  /// Interaction logic for UserControl1.xaml
  /// </summary>
  public partial class UserControl1 : UserControl
    {
    public UserControl1()
      {
      InitializeComponent();
      }
    private void button1_Click(object sender, RoutedEventArgs e)
      {
      // No Effect
      CommandManager.InvalidateRequerySuggested();
      }
    }
  }
The MenuItem and ToolBar button are both enabled and work. The two buttons on the window are disabled unless you move the command binding to this.CommandBindings.Add(SaveCmdBinding); then they also work.

BTW I really like the command system it makes it real easy to setup most of your basic toolbar and menu items. Ctrl+S also works in this program with no added code.

The reason I mentioned Focus is that if you don't bind the command directly to a target the default target is supposed to be the item with focus.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform