【问题标题】:ContextMenuItem isEnabled binding to Object propertyContextMenuItem isEnabled 绑定到 Object 属性
【发布时间】:2017-07-21 07:14:28
【问题描述】:

我有一个在树视图中声明的树视图项目的 ContextMenu:

<TreeView  ItemsSource="{Binding countries, Mode=TwoWay}" SelectedItemChanged="TreeView_SelectedItemChanged">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type myapp:City}"  ItemsSource="{Binding Cities}">
            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource CityItem}">
                <TextBlock Text="{Binding CityName}" FontSize="14" Foreground="Bisque"/>
                ...

而 ContextMenu 本身声明为:

<ContextMenu x:Key ="CityItem"  StaysOpen="true" Foreground="Bisque">
    <MenuItem Header="Edit City"  CommandParameter="{Binding Parent, RelativeSource={RelativeSource Self}}" Click="EditCityClick"/>
    <MenuItem Header="DeleteCity" CommandParameter="{Binding Parent, RelativeSource={RelativeSource Self}}" Click="DeleteCityClick"/>
</ContextMenu>

嗯,此时一切正常

private void DeleteCityClick(object sender, RoutedEventArgs e)
{
    City city = ((FrameworkElement)e.OriginalSource).DataContext as City;
        ...
}

我可以访问城市对象,修改,删除,根据城市和城市属性的变化在 gui 中更新所有内容(onpropertychanged 工作正常)。

问题是如何禁用 ContextMenuItem 绑定 IsEnabled 到 City 对象属性?比方说

public bool IsEnabled { get; set;}

我尝试了几种方法,但不知道如何从 ContextMenu MenuItem 访问源对象(城市)。

谢谢!

已编辑:抱歉打错了,但是:

public string IsEnabled { get; set;}

其实是:

public bool IsEnabled { get; set;}

编辑 2:

有趣的“不是 wpf...”

【问题讨论】:

  • 如果我没记错的话,你为什么不能简单地使用树视图的SelectedNode?如果打开上下文菜单并单击其中一个选项,则 SelectedNode 转换为 City 应该可以满足您的需求。 (而且你不需要使用 CommandParameter)
  • 其实我可能是错的,可以在不选择 TreeView 的情况下右键单击一个节点(我习惯于数据网格,这是不可能的)。看看at this link,它适用于 winforms,但转换为 WPF 应该没有那么困难。
  • senderMenuItemfind 属于哪个Menu,然后find 在哪个元素菜单上,然后这个元素的DataContext 是你的City
  • 对不起,也许我没有解释...我访问 City 对象没有问题...我想要将 City 对象的 Isenabled 属性绑定到MenuItem,不知道怎么绑定

标签: c# wpf data-binding contextmenu


【解决方案1】:

试试这个:

<MenuItem ... IsEnabled="{Binding PlacementTarget.DataContext.IsEnabled, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />

它绑定到父ContextMenuPlacementTargetDataContext,这应该是一个City 对象。

【讨论】:

  • 有RelativeSource ContextMenu这样的类型吗? ;)
  • 不 :) 它应该是 AncestorType。感谢您指出了这一点。我编辑了我的答案。
  • ... AncestorType 不是 wpf ... 都不起作用。 ..
  • @Hüsk3rDü:语法错误!查看我编辑的答案,然后重试:)
  • 如果你把RelativeSource={AncestorType ContextMenu}}你得到一个有趣的错误,看上面的截图...你必须把它改成RelativeSource={RelativeSource AncestorType=ContextMenu}}"
【解决方案2】:

我认为您的问题是,ContextMenu 在资源中。所以你可以使用 PlacementTarget 来绑定它。

<ContextMenu x:Key ="CityItem" IsEnabled="{Binding PlacementTarget.DataContext.IsEnabled, RelativeSource={RelativeSource Self}}">

【讨论】:

  • 好吧,我不需要转换器,因为 City 对象有一个名为 IsEnabled 的 bool 属性。另一方面,我只想禁用一个 ContextMenuitem。我试过 将 City 的 IsEnabled 属性设置为 false,但仍然无法正常工作...
  • 看我的回答。祖先类型错误。而且您不需要转换器。
  • @Hüsk3rDü 你的问题写了吗?公共字符串 IsEnabled { 获取;设置;}
  • 如果您想禁用单个 MenuItem,则不要这样做。
  • @Rekshino public bool IsEnabled {get; set;} 在 City 对象中定义...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 2019-12-25
相关资源
最近更新 更多