在关联菜单中手动设置分隔符的样式,使其与我的XAML版本具有相同的样式。WPF
当我右键单击在WPF中渲染的线条时,会打开一个上下文菜单。我想增加允许用户右键单击的余地,因此手动检查我的线条的坐标,以对照右键单击位置进行检查,如果我们点击了,打开一个上下文菜单,应该与他们在线条上右键单击完全相同 功能正常,但我的两个上下文菜单略有不同。以下是直接点击关联菜单:在关联菜单中手动设置分隔符的样式,使其与我的XAML版本具有相同的样式。WPF,wpf,contextmenu,Wpf,Contextmenu,当我右键单击在WPF中渲染的线条时,会打开一个上下文菜单。我想增加允许用户右键单击的余地,因此手动检查我的线条的坐标,以对照右键单击位置进行检查,如果我们点击了,打开一个上下文菜单,应该与他们在线条上右键单击完全相同 功能正常,但我的两个上下文菜单略有不同。以下是直接点击关联菜单: <Line.ContextMenu> <ContextMenu>
<Line.ContextMenu>
<ContextMenu>
<Separator>
<Separator.Template>
<ControlTemplate TargetType="Separator">
<StackPanel>
<TextBlock Text="{Binding Name}"></TextBlock>
<Separator/>
</StackPanel>
</ControlTemplate>
</Separator.Template>
</Separator>
<MenuItem Header="Normal" Command="{Binding SetNormalCommand}"></MenuItem>
<MenuItem Header="Reverse" Command="{Binding SetReverseCommand}"></MenuItem>
</ContextMenu>
</Line.ContextMenu>
if (CheckArea(point.NormalLine, clickX, clickY) || CheckArea(point.ReverseLine, clickX, clickY)) {
MenuItem header = new MenuItem{ Header = point.Name};
MenuItem norm = new MenuItem { Header ="Normal"};
MenuItem reverse = new MenuItem { Header ="Reverse"};
Separator sep = new Separator { };
norm.Command = point.SetNormalCommand;
reverse.Command = point.SetReverseCommand;
contextMenu = new ContextMenu();
contextMenu.Items.Add(header);
contextMenu.Items.Add(sep);
contextMenu.Items.Add(norm);
contextMenu.Items.Add(reverse);
contextMenu.IsOpen = true;
_window.ContextMenu = contextMenu;
break;
}
else {
contextMenu.IsOpen = false;
_window.ContextMenu = null;
}
以及此关联菜单的XAML:
<Line.ContextMenu>
<ContextMenu>
<Separator>
<Separator.Template>
<ControlTemplate TargetType="Separator">
<StackPanel>
<TextBlock Text="{Binding Name}"></TextBlock>
<Separator/>
</StackPanel>
</ControlTemplate>
</Separator.Template>
</Separator>
<MenuItem Header="Normal" Command="{Binding SetNormalCommand}"></MenuItem>
<MenuItem Header="Reverse" Command="{Binding SetReverseCommand}"></MenuItem>
</ContextMenu>
</Line.ContextMenu>
if (CheckArea(point.NormalLine, clickX, clickY) || CheckArea(point.ReverseLine, clickX, clickY)) {
MenuItem header = new MenuItem{ Header = point.Name};
MenuItem norm = new MenuItem { Header ="Normal"};
MenuItem reverse = new MenuItem { Header ="Reverse"};
Separator sep = new Separator { };
norm.Command = point.SetNormalCommand;
reverse.Command = point.SetReverseCommand;
contextMenu = new ContextMenu();
contextMenu.Items.Add(header);
contextMenu.Items.Add(sep);
contextMenu.Items.Add(norm);
contextMenu.Items.Add(reverse);
contextMenu.IsOpen = true;
_window.ContextMenu = contextMenu;
break;
}
else {
contextMenu.IsOpen = false;
_window.ContextMenu = null;
}
是否有任何代码我可以添加到我的手册版本,将得到相同的风格?提前谢谢
编辑:我应该提到直接点击的上下文菜单的“标题”是不可点击的,而区域的标题是可点击的,这是另一个区别 在C#code中,您正在为Name属性创建一个MenuItem
,但在XAML代码中,您已经为绑定Name属性的分隔符定义了一个DataTemplate
。这就是为什么在上下文菜单中会出现差异。因此,在代码隐藏中,还需要为分隔符定义DataTemplate
,而不是为Name属性定义新的MenuItem
。你可以按照下面的方法来做
if (CheckArea(point.NormalLine, clickX, clickY) || CheckArea(point.ReverseLine, clickX, clickY))
{
MenuItem norm = new MenuItem { Header ="Normal"};
MenuItem reverse = new MenuItem { Header ="Reverse"};
Separator sep = new Separator();
ControlTemplate dt = new ControlTemplate();
FrameworkElementFactory stackPanelElement = new FrameworkElementFactory(typeof(StackPanel));
dt.VisualTree = stackPanelElement;
FrameworkElementFactory txtElement = new FrameworkElementFactory(typeof(Textblock));
txtElement.SetValue(TextBlock.TextProperty, point.Name);
stackPanelElement.AppendChild(txtElement);
FrameworkElementFactory seperatorElement = new FrameworkElementFactory(typeof(Seperator));
stackPanelElement.AppendChild(seperatorElement);
sep.Template = dt;
norm.Command = point.SetNormalCommand;
reverse.Command = point.SetReverseCommand;
contextMenu = new ContextMenu();
contextMenu.Items.Add(sep);
contextMenu.Items.Add(norm);
contextMenu.Items.Add(reverse);
contextMenu.IsOpen = true;
_window.ContextMenu = contextMenu;
break;
}
else
{
contextMenu.IsOpen = false;
_window.ContextMenu = null;
}
在xaml Line.Resources标记中,您的上下文菜单如下所示:
<ContextMenu x:Key="ContextMenu">
<Separator>
<Separator.Template>
<ControlTemplate TargetType="Separator">
<StackPanel>
<TextBlock Text="{Binding Name}"></TextBlock>
<Separator/>
</StackPanel>
</ControlTemplate>
</Separator.Template>
</Separator>
<MenuItem Header="Normal" Command="{Binding SetNormalCommand}"></MenuItem>
<MenuItem Header="Reverse" Command="{Binding SetReverseCommand}"></MenuItem>
</ContextMenu>
<Line Name="ContextLine" ContextMenu="{DynamicResource ContextMenu}"/>
通过这种方式,您可以从Xaml获取相同的ContextMenu
,然后通过代码应用它。如果您在ContextMenu上添加一个键,那么您可以通过查看上述行的资源,从代码后面获取它,然后把它应用到回旋区。你能给我看一些XAML代码吗?这样我就能理解你的意思了?它本质上是在添加一个转换器,以便我可以检查上下文菜单的属性吗@感谢您的解决方案<代码>txtElement.SetBinding(TextBlock.TextProperty,point.Name)代码>给出错误“无法从“字符串”转换为System.Windows.Data.Binding.BindingBase”。你有什么想法吗?试试最新的答案。刚刚删除了绑定并直接分配了Text属性。PresentationFramework.dll“PN719B”中出现“System.ArgumentException”类型的未处理异常,无法添加文本,因为文本在此元素中无效。(PN719B是此实例中的点名称)你现在就可以试试,我正在应用MVVM实践,所以我的XAML没有代码隐藏。你知道有什么解决办法吗?编辑:我试着把\u window.TryFindResource(“ContextMenu”)作为ContextMenu
作为一种变通方法,但如果你在做MvvM,它就不起作用了。你的视图模型中的窗口在做什么?!视图模型中不允许有UI元素!没错,但这只是为了测试目的!底线是我的XAML文件中没有任何代码隐藏,我只是将_窗口传递到我的视图模型构造函数中尝试了一些东西:)如果您想在没有代码隐藏的情况下实现这一点,那么根本不要在C中实现。另一种选择是将其作为服务,但您还需要有代码来调用该服务。这个答案是基于您在代码隐藏中执行此操作。拥有处理UI的代码是绝对好的,您甚至可以从那里调用VM,这也很好。但永远不要在视图模型中使用UI!这包括上下文菜单
,菜单项
,分隔符
,框架元素工厂
等。。。