Wpf trainings DependencyObject-自定义命令

Wpf trainings DependencyObject-自定义命令,wpf,dependency-properties,dependencyobject,Wpf,Dependency Properties,Dependencyobject,我尝试创建从DependencyObject和ICommand继承的命令。我有以下代码: public class CustomCommand : DependencyObject, ICommand { public static readonly DependencyProperty CommandProperty; public static readonly DependencyProperty AfterCommandProperty; static C

我尝试创建从DependencyObject和ICommand继承的命令。我有以下代码:

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


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


谢谢

您的CustomCommand实例不在可视化树中,因此绑定是一个问题。无法获取数据上下文。尝试在绑定上放置跟踪:

<Button.Command>
    <local:CustomCommand
        Command="{Binding TestAction, PresentationTraceSources.TraceLevel=High}"
        />
</Button.Command>
将实例定义为某个包含范围中的资源,该范围具有所需的
操作
属性所在的
DataContext
{Binding}
不带路径只返回
DataContext
,在下面的例子中,它将是窗口的viewmodel

<Window.Resources>
    <local:BindingProxy
        x:Key="MainViewModelBindingProxy"
        Data="{Binding}"
        />
</Window.Resources>
请注意
您的
AfterCommand
属性中也有一个bug:它将
CommandProperty
传递给GetValue/SetValue,而不是
AfterCommandProperty

更改为:
Command=“{Binding Copy,PresentationTraceSources.TraceLevel=High}”
并查看调试输出中的内容。我怀疑您会发现没有上下文,因为它不在可视化树中。您可以尝试将命令创建为资源,和/或尝试各种绑定代理策略。顺便说一句,您在
AfterCommand
属性中有一个错误:它将
CommandProperty
传递给GetValue/SetValue,而不是
AfterCommandProperty
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));
}
<Window.Resources>
    <local:BindingProxy
        x:Key="MainViewModelBindingProxy"
        Data="{Binding}"
        />
</Window.Resources>
<Button
    Content="Custom Command Test"
    >
    <Button.Command>
        <local:CustomCommand
            Command="{Binding Data.TestAction, Source={StaticResource MainViewModelBindingProxy}}"
            />
    </Button.Command>
</Button>