8

RoutedCommand の CommandTarget プロパティを理解するのに苦労しています。

基本的に、(ウィンドウではなく) ユーザー コントロールに実装された静的コマンドがいくつかあります。ユーザー コントロールにコマンド バインドを作成します。ユーザー コントロールでボタンを宣言すると、ルーティング イベントを使用できます。ただし、ボタンがユーザー コントロールの外側にある場合、ルーティング イベントを使用できません。コマンドターゲットが私の問題を解決すると思います。

では、コンテナの Executed と CanExecuted が呼び出されるように、ツールバーのユーザー コントロールのボタンに commandtarget を設定するにはどうすればよいでしょうか。

micahtan の変更による変更を加えてコードを編集しましたが、まだ 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(); 
    }
}
4

2 に答える 2

8

CommandTargetsを使用する場合は、ButtonBaseで定義されているのと同様に、カスタムUserControlにCommandTargetDependencyPropertyを作成します。

その後、ボタンのCommandTargetをカスタムUserControlのCommandTargetに設定します。

編集:コードサンプル

Rudiのコメントは、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));
    }
}

テストプロジェクトでクラス名/名前空間の一部を変更したことに注意してください。ニーズに合わせて変更する必要があります。

于 2009-06-19T05:23:25.073 に答える
1

RelayCommand または DelegateCommand を使用することを検討しましたか? あなたが必要とするものにより適しているかもしれませんか?

RelayCommand の使用例については、 Josh によるこの記事を参照してください。

Brian Noyes の優れた記事もこちらから入手できます。

于 2009-06-19T06:34:23.490 に答える