2009-06-19 9 views
6

Mam trudności ze zrozumieniem właściwości CommandTarget dla RoutedCommand.Ustawianie celu polecenia w XAML

Zasadniczo mam pewne komendy statyczne, które mają implementacje w formancie użytkownika (nie okno). Tworzę wiązanie poleceń w kontrolce użytkownika. Jeśli zadeklaruję przycisk w sterowaniu użytkownika, będę mógł użyć mojego zdarzenia routowanego. Jeśli jednak przycisk znajduje się poza kontrolą użytkownika, nie mogę użyć zdarzenia routowanego. Myślę, że cel polecenia rozwiąże mój problem.

Jak ustawić parametr commandtarget dla przycisku kontrolnego użytkownika paska narzędzi, aby wywołać funkcje Container's Executed i CanExecuted?

Edytowany kod ze zmianami wprowadzonymi przez mikę, ale nadal nie mogę go pobrać do CanExecute lub Execute.

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

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

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

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

Pojemnik 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

Nie udało się uzyskać odpowiedź na moje pytanie jeszcze, ale jestem próbując pracować z tym, co do tej pory miałem. – kevindaub

+0

Opublikował kod, który powinien spowodować, że Twój scenariusz zadziała. – micahtan

+0

To naprawdę nie pomogło. Spróbuję jeszcze trochę później wieczorem. – kevindaub

Odpowiedz

7

Jeśli chcesz użyć CommandTargets, chciałbym stworzyć CommandTarget DependencyProperty na niestandardowym UserControl, podobny do sposobu, w jaki jest zdefiniowany na ButtonBase.

Po wykonaniu tej czynności ustaw CommandTarget przycisku w swoim niestandardowym CommandTarget UserControl.

EDIT: Przykładowy kod

komentarze Rudiego są ważne, jeśli robisz architekturę MVVM - RelayCommands lub jakąś inną formę owiniętych delegatów pracować również w tym przypadku. Na podstawie próbki Twojego kodu nie wyglądało to tak, jakbyś używał tego podejścia, stąd mój oryginalny komentarz.

Co do kodu, wystarczy zmienić tylko klasę ToolBar. Zakłada to, że twoja klasa MyCommand dziedziczy po RoutedUICommand. Oto 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> 

A oto kod z opóźnieniem:

użyciu System.Windows; przy użyciu 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)); 
    } 
} 

Proszę zauważyć, że zmieniłem niektóre nazwy/przestrzenie nazw w moim projekcie testowym. Będziesz musiał je zmienić, aby pasował do twoich potrzeb.

+0

Czy możesz podać małą próbkę kodu lub jakiś kierunek? – kevindaub

1

Podejrzewałeś, że wolisz używać polecenia RelayCommand lub DelegateCommand! Twoja może być bardziej dopasowana do tego, czego potrzebujesz?

Na przykład używając RelayCommand, przeczytaj artykuł this przez Josha

Brian Noyes mają również doskonały artykuł dostępny here

+0

DelegateCommand? Czy to część .Net czy dodatek? – kevindaub

+0

@rudigrobler - czy jesteś pewien, że RelayCommands zadziała w tym przypadku? Jego przykładowy kod zawiera Container i ToolBar jako rodzeństwo bez żadnych odniesień między nimi. – micahtan

+0

Relay/DelegateCommands nie są częścią struktury ... Pobierz z artykułu Josh'a lub pobierz Prism! Relay/DelegateCommand w ogóle nie polegają na drzewie Visual ... Dajesz każdemu poleceniu delegat do wykonania i to jest ... – rudigrobler

Powiązane problemy