培训 DependencyObject - 自定义命令
trainings DependencyObject - custom command
我尝试创建继承自 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>
当我按下测试按钮时,Command 和 AfterCommand 为空。你有好主意吗 ?最好的方法是什么,因为我无法将 ICommand 引用添加到我的 ViewModel。
谢谢
您的 CustomCommand 实例不在可视化树中,因此绑定是个问题。它无法获得 DataContext。尝试在绑定上添加跟踪:
<Button.Command>
<local:CustomCommand
Command="{Binding TestAction, PresentationTraceSources.TraceLevel=High}"
/>
</Button.Command>
"Framework mentor not found" 是您将在调试输出中看到的错误。 "Ya can't get there from here" 这就是他们所说的 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}
没有路径只有 returns DataContext
,在下面的例子中这将是 window 的视图模型。
<Window.Resources>
<local:BindingProxy
x:Key="MainViewModelBindingProxy"
Data="{Binding}"
/>
</Window.Resources>
然后像这样使用它。 BindingProxy
的Data
属性绑定到viewmodel,所以使用Data.WhateverPropertyYouWant
的路径。我叫我的 Action
属性 TestAction
。
<Button
Content="Custom Command Test"
>
<Button.Command>
<local:CustomCommand
Command="{Binding Data.TestAction, Source={StaticResource MainViewModelBindingProxy}}"
/>
</Button.Command>
</Button>
N.B.
您的 AfterCommand
属性 中也有错误:它将 CommandProperty
传递给 GetValue/SetValue,而不是 AfterCommandProperty
。
我尝试创建继承自 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>
当我按下测试按钮时,Command 和 AfterCommand 为空。你有好主意吗 ?最好的方法是什么,因为我无法将 ICommand 引用添加到我的 ViewModel。
谢谢
您的 CustomCommand 实例不在可视化树中,因此绑定是个问题。它无法获得 DataContext。尝试在绑定上添加跟踪:
<Button.Command>
<local:CustomCommand
Command="{Binding TestAction, PresentationTraceSources.TraceLevel=High}"
/>
</Button.Command>
"Framework mentor not found" 是您将在调试输出中看到的错误。 "Ya can't get there from here" 这就是他们所说的 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}
没有路径只有 returns DataContext
,在下面的例子中这将是 window 的视图模型。
<Window.Resources>
<local:BindingProxy
x:Key="MainViewModelBindingProxy"
Data="{Binding}"
/>
</Window.Resources>
然后像这样使用它。 BindingProxy
的Data
属性绑定到viewmodel,所以使用Data.WhateverPropertyYouWant
的路径。我叫我的 Action
属性 TestAction
。
<Button
Content="Custom Command Test"
>
<Button.Command>
<local:CustomCommand
Command="{Binding Data.TestAction, Source={StaticResource MainViewModelBindingProxy}}"
/>
</Button.Command>
</Button>
N.B.
您的 AfterCommand
属性 中也有错误:它将 CommandProperty
传递给 GetValue/SetValue,而不是 AfterCommandProperty
。