培训DependencyObject-自定义命令 [英] trainings DependencyObject - custom command

查看:145
本文介绍了培训DependencyObject-自定义命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to create Command which inherit from DependencyObject and ICommand. I have the following code:

    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>

当我按下测试按钮 Command AfterCommand >为空。你有想法吗 ?导致无法将ICommand引用添加到我的ViewModel的最佳方法是什么?

When I press Test button Command and AfterCommand are null. Do you have an idea ? What is the best way cause I can't add ICommand reference to my ViewModel.

谢谢

推荐答案

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

Your CustomCommand instance isn't in the visual tree, so binding is a problem. It's got no way to get a DataContext. Try putting a trace on the binding:

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

找不到框架导师是您将在调试输出中看到的错误。他们说唐老鸭说你不能从这里到那里。 XAML中的上下文是父母对父母的问题,但是从这个意义上来说,这件事没有父母。

"Framework mentor not found" is the error you'll see in the debug output. "Ya can't get there from here" is how they'd say that Down East. Context in XAML is a matter of parent-to-parent, but this thing has, in the sense that matters here, no parent.

但这是一个简单的解决方法。使用绑定代理。这是我从有关Stack Overflow的各种问题和答案中多次窃取的一种城市自行车实现方式:

But it's an easy fix. Use a binding proxy. Here's a town bike implementation that I've stolen several times from 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 ,在以下情况下,它将是窗口的视图模型。

Define an instance as a resource in some containing scope that has the DataContext where the desired Action property lives. {Binding} with no path just returns DataContext, which will be the window's viewmodel in the case below.

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

并像这样使用它。 BindingProxy Data 属性已绑定到视图模型,因此请使用 Data的路径。 WhateverPropertyYouWant 。我将我的 Action 属性称为 TestAction

And use it like so. The Data property of BindingProxy is bound to the viewmodel, so use a path of Data.WhateverPropertyYouWant. I called my Action property TestAction.

<Button
    Content="Custom Command Test"
    >
    <Button.Command>
        <local:CustomCommand
            Command="{Binding Data.TestAction, Source={StaticResource MainViewModelBindingProxy}}"
            />
    </Button.Command>
</Button>



NB



您还得到了 AfterCommand 属性中的错误:它会将 CommandProperty 传递给GetValue / SetValue,而不是 AfterCommandProperty

N.B.

You've also got a bug in your AfterCommand property: It's passing CommandProperty to GetValue/SetValue, not AfterCommandProperty.

这篇关于培训DependencyObject-自定义命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆