【发布时间】:2015-03-23 17:50:48
【问题描述】:
我正在尝试创建一个名为“DataTextBox”的 WPF 自定义控件。除了此控件的上下文菜单外,一切正常。事实上,我想在 DataTextBox 的上下文菜单中添加一个项目。为此,我在 generic.xaml 中定义的 DataTextBox 样式中添加了一个 MenuItem:
<Style TargetType="{x:Type controls:DataTextBox}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="{DynamicResource Components_TextBoxCut}" Command="ApplicationCommands.Cut" />
<MenuItem Header="{DynamicResource Components_TextBoxCopy}" Command="ApplicationCommands.Copy" />
<MenuItem Header="{DynamicResource Components_TextBoxPaste}" Command="ApplicationCommands.Paste" />
<MenuItem x:Name="menuItemInsertChecksum" Header="{DynamicResource Components_DataTextBoxInsertChecksum}"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:DataTextBox}}, Path=CalculateChecksumCommand}" />
</ContextMenu>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
...
</Setter.Value>
</Setter>
</Style>
我还在 DataTextBox 代码隐藏中添加了一个命令
public static DependencyProperty CalculateChecksumCommandProperty = DependencyProperty.Register("CalculateChecksumCommand", typeof(ICommand), typeof(DataTextBox));
public ICommand CalculateChecksumCommand { get; private set; }
此命令在 DataTextBox 构造函数中初始化:
public DataTextBox() : base()
{
CalculateChecksumCommand = new RelayCommand(() => CalculateChecksum(), () => CanCalculateChecksum());
}
我遇到的问题是我最后一个 MenuItem 的 Command 绑定不起作用,因为找不到“CalculateChecksumCommand”。这意味着永远不会调用“CalculateChecksum()”方法。
我将不胜感激有关该主题的任何帮助。谢谢。
编辑:依赖属性声明应该是:
public static DependencyProperty CalculateChecksumCommandProperty = DependencyProperty.Register("CalculateChecksumCommand", typeof(ICommand), typeof(DataTextBox));
public ICommand CalculateChecksumCommand
{
get { return (ICommand)GetValue(CalculateChecksumCommandProperty); }
private set { SetValue(CalculateChecksumCommandProperty, value); }
}
【问题讨论】:
-
您没有在这里使用您的 DP:您只是创建了它并创建了一个属性。 CalculateChecksumCommand 不会通知接口的任何更改。请看如何声明 DP:msdn(注意这可能不是问题)
-
当您需要使用不受您控制的属性时,请使用 DP:这里不是这种情况。使用 Commands & Binding 与 ViewModel 层通信,避免它与 View 层通信。与 RelativeSource 的绑定应该不是问题,但永远不要根据自定义控件中的 DataContext 使用绑定。您的代码的问题在于它在不应该向外界公开CalculateChecksumCommand(您应该只公开外部世界可以使用的内容,而您的财产并非如此)
-
@nkoniishvt,好的,我明白了。我已经编辑了我的第一篇文章,以正确的方式声明 DP。
-
@nkoniishvt,事实上,我想使用一个命令,以便在必要时自动禁用我的 MenuItem。这可能不是最好的方法。我应该如何实现这种行为?我应该使用 MenuItem 的点击事件吗?如果是这样,怎么做? (我试了很多次都没有成功)
-
这是正确的做法,只是您的组件应该公开一个 ICommand DP 并让使用者设置它。自定义控件应尽可能“通用”,在这里您的控件将仅在一种情况下工作:计算似乎的校验和。我不是最有经验的 WPF 开发人员,但我认为你应该做的是公开一个 ICommand DP 并在回调函数中设置你的 menuItemInsertChecksum 的 Command DP。 (当你暴露的 ICommand 被设置时,设置 MenuItem 的命令)
标签: c# wpf command custom-controls