Установка цели команды в XAML - PullRequest
6 голосов
/ 19 июня 2009

Мне трудно понять свойство CommandTarget для RoutedCommand.

По сути, у меня есть несколько статических команд, которые имеют реализации в пользовательском элементе управления (не в окне). Я создаю привязку команд в пользовательском элементе управления. Если я объявлю кнопку в пользовательском контроле, то смогу использовать перенаправленное событие. Однако, когда кнопка находится вне пользовательского контроля, я не могу использовать перенаправленное событие. Я думаю, что командная цель решит мою проблему.

Так как мне установить целевой объект команды для кнопки usercontrol на панели инструментов, чтобы вызывался Контейнер Executed и CanExecuted?

Отредактированный код с изменениями из изменений в Михахте, но я все еще не могу передать его в CanExecute или Execute. Окно 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(); 
    }
}

Ответы [ 2 ]

8 голосов
/ 19 июня 2009

Если вы хотите использовать CommandTargets, я бы создал CommandTarget DependencyProperty для вашего пользовательского элемента управления UserControl, аналогично тому, как он определен в ButtonBase.

После этого установите CommandTarget вашей кнопки равным 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; использование 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));
    }
}

Обратите внимание, что я изменил некоторые имена классов / пространства имен в моем тестовом проекте. Вам придется изменить их в соответствии с вашими потребностями.

1 голос
/ 19 июня 2009

Вы решили скорее использовать RelayCommand или DelegateCommand! Твой может быть более подходящим для того, что тебе нужно?

Для примера использования RelayCommand прочитайте эту статью Джоша

У Брайана Нойеса также есть отличная статья здесь

...