代码之家  ›  专栏  ›  技术社区  ›  Pat

将同一组命令附加/绑定到多个控件

  •  0
  • Pat  · 技术社区  · 14 年前

    我在画布中有一个控件,我希望能够使用箭头键移动它。为了尝试,我创建了下面的类,它可以满足我的需要。

    <Window x:Class="DiagramDesigner.CanvasControlArrowKeyTest"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            Title="CanvasControlArrowKeyTest" Height="300" Width="300">
        <Canvas>
            <Canvas.InputBindings>
                <KeyBinding Key="Down" Command="MoveDown" />
                <KeyBinding Key="Up" Command="MoveUp" />
                <KeyBinding Key="Right" Command="MoveRight" />
                <KeyBinding Key="Left" Command="MoveLeft" />
            </Canvas.InputBindings>
            <Button>
                <Button.CommandBindings>
                    <CommandBinding Command="MoveDown" Executed="MoveDown_Executed" />
                    <CommandBinding Command="MoveUp" Executed="MoveUp_Executed" />
                    <CommandBinding Command="MoveLeft" Executed="MoveLeft_Executed" />
                    <CommandBinding Command="MoveRight" Executed="MoveRight_Executed" />
                </Button.CommandBindings>
            </Button>
        </Canvas>
    </Window>
    

    下面是一段代码:

    private void MoveDown_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        var uiElement = (UIElement)sender;
        double value = Canvas.GetTop(uiElement);
        value = Double.IsNaN(value) ? 0 : value;
        value++;
        Canvas.SetTop(uiElement, value < 0 ? 0 : value);
    }
    

    这一切都很好,但我真正想要的是一堆有这个能力的按钮,而不仅仅是那个。如何确保每个按钮都有这些CommandBindings?如果有比使用CommandBindings更简单的方法,那会是什么呢?

    <Window x:Class="DiagramDesigner.CanvasControlArrowKeyTest"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            Title="CanvasControlArrowKeyTest" Height="300" Width="300">
        <Window.CommandBindings>
            <CommandBinding Command="MoveDown" Executed="MoveDown_Executed" />
            <CommandBinding Command="MoveUp" Executed="MoveUp_Executed" />
            <CommandBinding Command="MoveLeft" Executed="MoveLeft_Executed" />
            <CommandBinding Command="MoveRight" Executed="MoveRight_Executed" />
        </Window.CommandBindings>
        <Window.InputBindings>
            <KeyBinding Key="Down" Command="MoveDown" />
            <KeyBinding Key="Up" Command="MoveUp" />
            <KeyBinding Key="Right" Command="MoveRight" />
            <KeyBinding Key="Left" Command="MoveLeft" />
        </Window.InputBindings>
        <Canvas >
            <Button Width="50" Height="50" />
        </Canvas>
    </Window>
    

    C类#

    private void MoveDown_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        var uiElement = (UIElement)e.OriginalSource; // Still doesn't point to the Button
        double value = Canvas.GetTop(uiElement);
        value = Double.IsNaN(value) ? 0 : value;
        value++;
        Canvas.SetTop(uiElement, value < 0 ? 0 : value);
    }
    

    更新:我放弃了这种方法。我最后用了一个 different solution 对于这个问题,一个不使用命令的人。

    2 回复  |  直到 8 年前
        1
  •  0
  •   Michael Meadows    14 年前

    您应该查看路由事件处理程序: http://msdn.microsoft.com/en-us/library/ms742806.aspx

    上面的链接有一个例子说明了如何做你想做的事情。

    <Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
      <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
        <Button Name="YesButton" Width="Auto" >Yes</Button>
        <Button Name="NoButton" Width="Auto" >No</Button>
        <Button Name="CancelButton" Width="Auto" >Cancel</Button>
      </StackPanel>
    </Border>
    

    private void CommonClickHandler(object sender, RoutedEventArgs e)
    {
      FrameworkElement feSource = e.Source as FrameworkElement;
      switch (feSource.Name)
      {
        case "YesButton":
          // do something here ...
          break;
        case "NoButton":
          // do something ...
          break;
        case "CancelButton":
          // do something ...
          break;
      }
      e.Handled=true;
    }
    
        2
  •  0
  •   mdm20    14 年前

    如果在顶级对象(本例中是窗口)中创建commandbindings,则可以将它们用于窗口的任何子级。

    <Window x:Class="TesterApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:data="clr-namespace:TesterApp"
            x:Name="TheMainWindow"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
        </Window.Resources>
        <Window.InputBindings>
            <KeyBinding Key="A" Command="MoveDown" />
        </Window.InputBindings>
        <Window.CommandBindings>
            <CommandBinding Command="MoveDown" Executed="MoveDown_Executed" />
        </Window.CommandBindings>
        <Grid>
            <Button Height="30" Width="80" Content="Click" Command="MoveDown" />
        </Grid>
    </Window>