将上下文菜单项与依赖属性绑定

发布于 2024-09-10 07:59:38 字数 3061 浏览 3 评论 0原文

我有一个自定义画布(DesignerCanvas),用户可以向该画布添加一些控件。在添加任何控件画布之前,首先将其包装在自定义控件(设计器项)中,然后将该控件添加到画布。

这是按照此代码项目文章中完成的 -

WPF 图表设计器 - http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part4.aspx

我为 DesignerCanvas 和 DesignerItem 添加了上下文菜单,其中有一个名为“Lock”的菜单项。我还在画布中添加了一个名为“IsLocked”的属性来锁定画布。

现在,在上下文菜单中,如果画布被锁定,我想显示一个复选标记,为此,我将 IsLocked 属性绑定到 MenuItem 的“IsChecked”属性。问题是它适用于 DesignerCanvas cantext 菜单,但不适用于 DesignerItems 上下文菜单。

DesignerCanvas ContextMenu 代码,这工作正常 -

<!-- Context menu for DesignerCanvas -->
<ContextMenu x:Key="DesignerCanvasContextMenu">
  <!-- Other menu items -->
  <MenuItem IsCheckable="True" Header="Lock"
    IsChecked="{Binding Path=IsLocked, Mode=TwoWay,
     RelativeSource={RelativeSource AncestorType={x:Type locl:DesignerCanvas}}}"
    Command="{x:Static local:DesignerCanvas.LockUnLock}"
    CommandParameter="{Binding RelativeSource={RelativeSource Self}, 
     Path=IsChecked}"
    CommandTarget="{Binding Path=PlacementTarget,
     RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}">
  </MenuItem>
</ContextMenu>

也需要为 DesignerItem 菜单实现相同的行为。我尝试这样做,但它不起作用 -

<!-- Context menu for DesignerItem -->
<ContextMenu x:Key="DesignerItemContextMenu">
  <!-- Other menu items -->
  <MenuItem IsCheckable="True" Header="Lock"
    IsChecked="{Binding Path=Parent.IsLocked, Mode=TwoWay,
      RelativeSource={RelativeSource AncestorType={x:Type locl:DesignerItem}}}"
    Command="{x:Static local:DesignerCanvas.LockUnLock}"
    CommandParameter="{Binding RelativeSource={RelativeSource Self}, 
     Path=IsChecked}"
    CommandTarget="{Binding Path=PlacementTarget,
     RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}">
  </MenuItem>
</ContextMenu>

我也尝试使用 PlacementTarget 这样做,但没有成功。由于 DesignerItem 是 DesignerCanvas 的子项,因此应该不可能获取 DesignerCanvas 及其属性。我做错了什么,有什么想法吗?

更新:

我将上下文菜单附加到 DesignerCanvas 和 Designer Item,如下所示 -

<!-- DesignerItem || Style -->
<Style TargetType="{x:Type locl:DesignerItem}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:DesignerItem}">
        <Grid x:Name="PART_Grid" Cursor="SizeAll"
          DataContext="{Binding RelativeSource={RelativeSource TemplatedParent} 
,Path=.}"
          ContextMenu="{StaticResource DesignerItemContextMenu}">

          <!-- other template parts -->

        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>


<!-- DesignerCanvas || Style -->
<Style
    TargetType="{x:Type locl:DesignerCanvas}">
    <Setter
        Property="ContextMenu"
        Value="{StaticResource DesignerCanvasContextMenu}" />
</Style>

I have a Custom Canvas(DesignerCanvas), user can add some controls to this canvas. Before adding any control canvas first wraps it insdie a custom control(Designer Item) and then add that control to canvas.

This is done as in this codeproject article -

WPF Diagram Designer -
http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part4.aspx

I have added context menus for both DesignerCanvas and DesignerItem having a menu item named 'Lock'. I have also added a property in canvas named "IsLocked" to lock the canvas.

Now, in the context menu I want to show a check mark if canvas is locked, to do this I have bound the IsLocked property to 'IsChecked' property of MenuItem. Problem is that it works for the DesignerCanvas cantext menu but not for DesignerItems context menu.

DesignerCanvas ContextMenu code, this works fine -

<!-- Context menu for DesignerCanvas -->
<ContextMenu x:Key="DesignerCanvasContextMenu">
  <!-- Other menu items -->
  <MenuItem IsCheckable="True" Header="Lock"
    IsChecked="{Binding Path=IsLocked, Mode=TwoWay,
     RelativeSource={RelativeSource AncestorType={x:Type locl:DesignerCanvas}}}"
    Command="{x:Static local:DesignerCanvas.LockUnLock}"
    CommandParameter="{Binding RelativeSource={RelativeSource Self}, 
     Path=IsChecked}"
    CommandTarget="{Binding Path=PlacementTarget,
     RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}">
  </MenuItem>
</ContextMenu>

Need to do achive same behavior for DesignerItem menu too. I tried doing this but it doesn't work -

<!-- Context menu for DesignerItem -->
<ContextMenu x:Key="DesignerItemContextMenu">
  <!-- Other menu items -->
  <MenuItem IsCheckable="True" Header="Lock"
    IsChecked="{Binding Path=Parent.IsLocked, Mode=TwoWay,
      RelativeSource={RelativeSource AncestorType={x:Type locl:DesignerItem}}}"
    Command="{x:Static local:DesignerCanvas.LockUnLock}"
    CommandParameter="{Binding RelativeSource={RelativeSource Self}, 
     Path=IsChecked}"
    CommandTarget="{Binding Path=PlacementTarget,
     RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}">
  </MenuItem>
</ContextMenu>

I tried to do this using PlacementTarget too but was not successful. As DesignerItem is DesignerCanvas's child it should not be impossible to get hold of the DesignerCanvas and in turn its property. What am I doing wrong, any idea?

Update:

I am attaching the context menu with DesignerCanvas and Designer Item like this -

<!-- DesignerItem || Style -->
<Style TargetType="{x:Type locl:DesignerItem}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:DesignerItem}">
        <Grid x:Name="PART_Grid" Cursor="SizeAll"
          DataContext="{Binding RelativeSource={RelativeSource TemplatedParent} 
,Path=.}"
          ContextMenu="{StaticResource DesignerItemContextMenu}">

          <!-- other template parts -->

        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>


<!-- DesignerCanvas || Style -->
<Style
    TargetType="{x:Type locl:DesignerCanvas}">
    <Setter
        Property="ContextMenu"
        Value="{StaticResource DesignerCanvasContextMenu}" />
</Style>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神爱温柔 2024-09-17 07:59:38

只是一个快速猜测:

您是否尝试过以与画布相同的方式在 DesignerItem 上设置上下文菜单?像这样:

<Style TargetType="{x:Type locl:DesignerItem}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:DesignerItem}">
        <Grid x:Name="PART_Grid" Cursor="SizeAll"
          DataContext="{Binding RelativeSource={RelativeSource TemplatedParent} 
,Path=.}">

          <!-- other template parts -->

        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Setter
    Property="ContextMenu"
    Value="{StaticResource DesignerItemContextMenu}" />
</Style>

除此之外,我真的建议您在您的应用程序上启动 Snoop 并在以下位置查找绑定错误你的上下文菜单

just a quick guess:

have you tried setting your Contextmenu on DesignerItem the same Way as for the Canvas? like so:

<Style TargetType="{x:Type locl:DesignerItem}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:DesignerItem}">
        <Grid x:Name="PART_Grid" Cursor="SizeAll"
          DataContext="{Binding RelativeSource={RelativeSource TemplatedParent} 
,Path=.}">

          <!-- other template parts -->

        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Setter
    Property="ContextMenu"
    Value="{StaticResource DesignerItemContextMenu}" />
</Style>

other than that, I really recommend you fire up Snoop on your application and look for binding errors in your context menu

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文