2009-06-19 156 views
6

我很難理解RoutedCommand的CommandTarget屬性。在XAML中設置命令目標

基本上,我有一些在用戶控件(不是窗口)中具有實現的靜態命令。我在用戶控件中創建一個命令綁定。如果我在usercontrol中聲明按鈕,那麼我可以使用我的路由事件。但是,當該按鈕位於usercontrol外部時,我無法使用路由事件。我認爲命令目標將解決我的問題。

那麼如何設置工具欄usercontrol的按鈕的命令目標,以便調用Container的Executed和CanExecuted?

編輯代碼與micahtan變化的變化,但我仍然無法得到它CanExecute或執行。

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

工具欄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> 

工具欄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); } 
     } 
    } 

集裝箱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> 

集裝箱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

我一直沒能得到回答我的問題,但我試圖與我目前的工作。 – kevindaub 2009-06-20 22:05:01

+0

發佈了一些應該讓你的場景起作用的代碼。 – micahtan 2009-06-22 17:19:58

+0

它並沒有真正的幫助。今晚晚些時候我會再嘗試一些。 – kevindaub 2009-06-22 22:53:32

回答

7

如果你想使用CommandTargets,我會在你的自定義用戶控件,類似於它的上ButtonBase定義方式創建CommandTarget的DependencyProperty。

做完這些之後,將Button的CommandTarget設置爲您的自定義UserControl的CommandTarget。

編輯:代碼示例

魯迪的評論是有效的,如果你正在做一個MVVM體系結構 - RelayCommands或包裹代表的一些其他形式在這種情況下正常工作。根據你的代碼示例,它看起來並不像你使用這種方法,因此我的原始評論。

至於代碼,你只需要改變你的ToolBar類。這假設你的MyCommand類繼承自RoutedUICommand。這裏的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> 

而這裏的代碼隱藏:使用System.Windows

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

請注意,我在我的測試項目中更改了一些類名/名稱空間。你必須改變它們以適應你的需求。

+0

你能提供一個小代碼示例或某個方向嗎? – kevindaub 2009-06-19 22:15:55

1

您是否曾經勉強使用RelayCommand或DelegateCommand!你可能更適合你需要的東西?

對於使用RelayCommand的例子,讀this文章由Josh

布賴恩·諾伊斯也有一個可用的優秀文章here

+0

DelegateCommand?是.Net的一部分還是附加的? – kevindaub 2009-06-19 22:17:44

+0

@rudigrobler - 你確定RelayCommands可以在這種情況下工作嗎?他的代碼示例將Container和ToolBar作爲兄弟之間沒有任何參考。 – micahtan 2009-06-19 22:27:32

+0

Relay/DelegateCommands不是框架的一部分...從Josh的文章中獲得它或下載Prism! Relay/DelegateCommand根本不依賴Visual樹......你給每個命令一個委託來執行,就是這樣...... – rudigrobler 2009-06-22 08:10:27