在上下文菜单中设置时 WPF CommandParameter 未更新
我有一个带有几个文本框控件的 wpf 窗口。我需要应用一种通用样式,将上下文菜单应用于每个控件,并且我已将其全局定义如下,
<ContextMenu x:Key="textBoxMenu">
<Separator/>
<MenuItem Header="Affirm"
Command="{Binding Path=AffirmCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBox},AncestorLevel=1}}"/>
</ContextMenu>
<Style TargetType="{x:Type TextBox}" x:Key="TextBoxAffirmMenuStyle">
<Setter Property="ContextMenu" Value="{DynamicResource textBoxMenu}" />
</Style>
我使用命令根据上下文菜单的目标执行适当的方法,在本例中是文本框。
为了唯一地标识控件,我使用唯一的字符串设置了每个控件的“标签”属性,并从设置为目标文本框控件本身的命令参数访问此标签。
private bool CanAffirmExecute(object param)
{
string columnName = (param as FrameworkElement).Tag as string;
if (this.CheckIsAffirmed(columnName))
return true;
else
return false;
}
private void AffirmExecute(object param)
{
string columnName = (param as FrameworkElement).Tag as string;
this.Affirm(columnName);
}
这样做的问题是,一旦命令参数设置为特定控件, 当右键单击不同的控件时,后续的上下文菜单操作不会改变。 Command 参数保持静态,仅获取第一个控件中设置的标记值。
我怎样才能让它工作,以便我可以使用命令访问控件的每个标签值?
谢谢。
I have a wpf window with several text box controls. I need to apply a common style that would apply a context menu to each control and i have defined it globally as follows,
<ContextMenu x:Key="textBoxMenu">
<Separator/>
<MenuItem Header="Affirm"
Command="{Binding Path=AffirmCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBox},AncestorLevel=1}}"/>
</ContextMenu>
<Style TargetType="{x:Type TextBox}" x:Key="TextBoxAffirmMenuStyle">
<Setter Property="ContextMenu" Value="{DynamicResource textBoxMenu}" />
</Style>
I Have used a Command to execute the appropriate method depending on the target of the context menu, which is in this case the text box.
To identify the controls uniquely, i have set the "Tag" property of each control with a unique string and i access this tag from the command parameter which is set to the target text box Control itself.
private bool CanAffirmExecute(object param)
{
string columnName = (param as FrameworkElement).Tag as string;
if (this.CheckIsAffirmed(columnName))
return true;
else
return false;
}
private void AffirmExecute(object param)
{
string columnName = (param as FrameworkElement).Tag as string;
this.Affirm(columnName);
}
The problem with this is that once the command parameter gets set to a particular control,
it will not change on subsequent context menu operations when right clicked on a different control. the Command parameter remains static and gets only the tag value set in the first control.
How can i get this to work so that i can access each of the tag values of the controls using the command?
thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ContextMenu 位于其自己的可视化树的根部,因此使用RelativeSource.FindAncestor 的任何绑定都不会越过ContextMenu。
解决方法是使用具有 PlacementTarget 属性的两阶段绑定,如下所示:
并分析 OnAffirmCommand(object obj) 方法中的对象参数来控制您的行为。在本例中,该对象是实际的 TextBox。
这是上下文菜单定义:
这是文本框:
这是来自 ViewModel 的命令代码:
ContextMenu is at the root of its own visual tree, so any binding using RelativeSource.FindAncestor does not go past the ContextMenu.
A work around is to use a two stage binding with the PlacementTarget property as follows,
and to analyse the object parameter in the method OnAffirmCommand(object obj) to control your behaviour. In this case the object is the actual TextBox.
Here is the context menu definition:
Here are the text boxes:
Here is the command code from a ViewModel: