2009-06-19 8 views
6

Tengo dificultades para entender la propiedad CommandTarget para un RoutedCommand.Configuración del objetivo del comando en XAML

Básicamente, tengo algunos comandos estáticos que tienen implementaciones en un control de usuario (no en la ventana). Creo un enlace de comando en el control de usuario. Si declaro el botón en el control de usuario, entonces puedo usar mi evento enrutado. Sin embargo, cuando el botón está fuera del control de usuario, no puedo usar mi evento enrutado. Creo que el objetivo del comando resolverá mi problema.

Entonces, ¿cómo configuro el commandtarget para el botón de control de usuario de la barra de herramientas, para que se ejecute el contenedor ejecutado y el comando CanExecuted?

Código editado con cambios de micahtan cambia, pero todavía no puedo obtenerlo en CanExecute o Execute.

Ventana XAML:

<Window x:Class="RoutedCommands.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:RoutedCommands" 
    xmlns:toolbar="clr-namespace:RoutedCommands.Toolbar" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <local:Container Width="100" Height="25" x:Name="MyContainer" /> 
     <toolbar:Toolbar Width="100" Height="25" CommandTarget="{Binding MyContainer}" /> 
    </StackPanel> 
</Window> 

Barra de herramientas de XAML:

<UserControl x:Class="RoutedCommands.Toolbar.Toolbar" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:RoutedCommands" 
    x:Name="MyToolbar" 
    Height="300" Width="300"> 
    <Grid> 
     <Button Command="{x:Static local:Commands.MyCommand}" Content="Try Me" CommandTarget="{Binding ElementName=MyToolbar, Path=CommandTarget, Mode=OneWay}" /> 
    </Grid> 
</UserControl> 

Barra de herramientas de CS:

public partial class Toolbar : UserControl 
    { 
     public Toolbar() 
     { 
      InitializeComponent(); 
     } 

     // Using a DependencyProperty as the backing store for CommandTarget. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty CommandTargetProperty = 
       DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(Toolbar), new UIPropertyMetadata(null)); 

     public IInputElement CommandTarget 
     { 
      get { return (IInputElement)GetValue(CommandTargetProperty); } 
      set { SetValue(CommandTargetProperty, value); } 
     } 
    } 

Container XAML:

<UserControl x:Class="RoutedCommands.Container" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:RoutedCommands" 
    Height="300" Width="300"> 
    <UserControl.CommandBindings> 
     <CommandBinding Command="{x:Static local:Commands.MyCommand}" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed" /> 
    </UserControl.CommandBindings> 
    <Grid> 
     <Button Command="{x:Static local:Commands.MyCommand}" Content="Click Me" /> 
    </Grid> 
</UserControl> 

Container CS:

public partial class Container : UserControl 
{ 
    public Container() 
    { 
     InitializeComponent(); 
    } 

    private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) 
    { 
     Console.WriteLine("My Command Executed"); 
    } 

    private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) 
    { 
     Console.WriteLine("My Command Can Execute"); 
     e.CanExecute = true; 
    } 
} 

RoutedCommands:

namespace RoutedCommands 
{ 
    public static class Commands 
    { 
     public static readonly RoutedUICommand MyCommand = new RoutedUICommand(); 
    } 
} 
+0

no he sido capaz de obtener una respuesta a mi pregunta todavía, pero estoy tratando de trabajar con lo que tengo hasta ahora. – kevindaub

+0

Publicó un código que debería hacer funcionar su escenario. – micahtan

+0

Realmente no ayudó. Voy a intentar algo más tarde esta noche. – kevindaub

Respuesta

7

Si desea utilizar CommandTargets, me gustaría crear un CommandTarget DependencyProperty en su control de usuario personalizada, similar a la forma en que se define en ButtonBase.

Después de hacer eso, configure la CommandTarget de su Botón en la CommandTarget personalizada de UserControl.

EDIT: Código de ejemplo

comentarios de Rudi son válidas si está haciendo una arquitectura MVVM - RelayCommands o alguna otra forma de delegados envueltos funcionan bien en ese caso. Según tu muestra de código, no parecía que estuvieras usando ese enfoque, de ahí mi comentario original.

En cuanto al código, solo necesita cambiar su clase ToolBar. Esto supone que su clase MyCommand hereda de RoutedUICommand. Aquí está el XAML:

<UserControl 
    x:Class="WPFCommandTarget.CustomToolBar" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WPFCommandTarget" 
    x:Name="theControl"> 
    <Grid> 
     <Button 
      x:Name="theButton" 
      Command="{x:Static local:Commands.MyCommand}" 
      CommandTarget="{Binding ElementName=theControl, Path=CommandTarget, Mode=OneWay}" 
      Content="Try Me" /> 
    </Grid> 
</UserControl> 

Y aquí está el código subyacente:

usando System.Windows; usando System.Windows.Controls;

namespace WPFCommandTarget 
{ 
    /// <summary> 
    /// Interaction logic for CustomToolBar.xaml 
    /// </summary> 
    public partial class CustomToolBar : UserControl 
    { 
     public CustomToolBar() 
     { 
      InitializeComponent(); 
     } 

     public IInputElement CommandTarget 
     { 
      get { return (IInputElement)GetValue(CommandTargetProperty); } 
      set { SetValue(CommandTargetProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for CommandTarget. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty CommandTargetProperty = 
      DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(CustomToolBar), new UIPropertyMetadata(null)); 
    } 
} 

Tenga en cuenta que he cambiado algunos de los nombres de clase/espacios de nombres en mi proyecto de prueba. Tendrá que cambiarlos para adaptarlos a sus necesidades.

+0

¿Podría proporcionar una pequeña muestra de código o alguna dirección? – kevindaub

1

¿Ha considerado utilizar el RelayCommand o DelegateCommand en su lugar? ¿Podría ser más adecuado para lo que necesitas?

Para un ejemplo del uso de RelayCommand, leer this artículo de Josh

Brian Noyes también tienen un excelente artículo disponible here

+0

DelegateCommand? ¿Es eso parte de .Net o un complemento? – kevindaub

+0

@rudigrobler: ¿está seguro de que RelayCommands funcionaría en esta instancia? Su ejemplo de código tiene el contenedor y la barra de herramientas como hermanos sin referencias entre ellos. – micahtan

+0

Relay/DelegateCommands no son parte del marco ... ¡Obténgalo del artículo de Josh o descargue Prism! Relay/DelegateCommand no confíe en el árbol de Visual en absoluto ... Le da a cada comando un delegado para ejecutar y eso es todo ... – rudigrobler

Cuestiones relacionadas