培训DependencyObject-自定义命令 [英] trainings DependencyObject - custom command
问题描述
我尝试创建从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屋!