training DependencyObject - 自定义命令

时间:2017-05-09 17:51:01

标签: wpf dependency-properties dependencyobject

我尝试创建继承自DependencyObject和ICommand的Command。我有以下代码:

    public class CustomCommand : DependencyObject, ICommand
{
    public static readonly DependencyProperty CommandProperty;
    public static readonly DependencyProperty AfterCommandProperty;
    static CustomCommand()
    {
        var ownerType = typeof(CustomCommand);
        CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(Action), ownerType, new PropertyMetadata(null));
        AfterCommandProperty = DependencyProperty.RegisterAttached("AfterCommand", typeof(Action), ownerType, new PropertyMetadata(null));
    }

    public Action Command
    {
        get => (Action)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    public Action AfterCommand
    {
        get => (Action)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        // Command & AfterCommand are always null
    }
}

    <Button Content="Test">
    <Button.Command>
        <command:CustomCommand  Command="{Binding Copy}" AfterCommand="{Binding AfterCopy}" />
    </Button.Command>
</Button>

当我按下测试按钮命令 AfterCommand 为空时。你有好主意吗 ?什么是最好的方法,因为我无法将ICommand引用添加到我的ViewModel。

由于

1 个答案:

答案 0 :(得分:0)

您的CustomCommand实例不在可视树中,因此绑定是一个问题。它无法获得DataContext。尝试对绑定进行跟踪:

<Button.Command>
    <local:CustomCommand
        Command="{Binding TestAction, PresentationTraceSources.TraceLevel=High}"
        />
</Button.Command>

“找不到框架导师”是您在调试输出中看到的错误。 “雅不能从这里到达那里”是他们怎么说Down East。 XAML中的上下文是父母对父母的问题,但从某种意义上来说,这个问题与父母无关。

但这很容易解决。使用绑定代理。这是我从various questions and answers on Stack Overflow多次偷走的城镇自行车实施:

public class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

将实例定义为某个包含范围的资源,该范围具有所需DataContext属性所在的Action。没有路径的{Binding}只返回DataContext,这将是下面案例中窗口的viewmodel。

<Window.Resources>
    <local:BindingProxy
        x:Key="MainViewModelBindingProxy"
        Data="{Binding}"
        />
</Window.Resources>

并像这样使用它。 Data的{​​{1}}属性绑定到viewmodel,因此请使用BindingProxy的路径。我打电话给我的Data.WhateverPropertyYouWant财产Action

TestAction

N.B。

您的<Button Content="Custom Command Test" > <Button.Command> <local:CustomCommand Command="{Binding Data.TestAction, Source={StaticResource MainViewModelBindingProxy}}" /> </Button.Command> </Button> 媒体资源中也有一个错误:它正在将AfterCommand传递给GetValue / SetValue,而不是CommandProperty