确定在WPF容器中触发上下文菜单的绑定对象?

时间:2019-03-06 13:53:07

标签: c# wpf data-binding

(整个查询基于以下假设:我可以在一个单独的文件中创建一个上下文菜单,并将其附加到不同控件中的不同容器上-应该验证该假设)

如何确定触发上下文菜单操作的容器项目中的绑定对象?

我可以通过查看ListView的SelectedItem来了解如何执行此操作,但我不想不必了解特定的ListView实例,例如因此相同的上下文菜单可以附加到不同的列表。

即使在不同类型的容器中(例如,不一定是ListView),是否存在用于确定绑定对象的通用解决方案?

<UserControl ...>

    <UserControl.Resources>
        <ContextMenu x:Key="ContextMenu">
            <MenuItem Header="Caption" Click="MenuItem_Click"></MenuItem>
        </ContextMenu>
    </UserControl.Resources>

    <ListView x:Name="ListView">
        <ListView.ContextMenu>
            <StaticResource ResourceKey="ContextMenu" />
        </ListView.ContextMenu>
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
            </GridView>
        </ListView.View>
    </ListView>

</UserControl>

鉴于上述控制,如何获得被单击项的绑定对象? 我淹没在RoutedEventArgs的属性汤中。

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
  var obj = ??? as MyObjType;
  var name = obj.Name;
}

这似乎按预期工作,但已硬编码到容器实例:

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    var obj = (MyObjType)NodesList.SelectedItem;
    MessageBox.Show(obj.Name);
}

2 个答案:

答案 0 :(得分:0)

如果要使用通用方法,可以尝试仅通过鼠标坐标获取控件。菜单打开时,您需要获取它们:

<ContextMenu x:Key="ContextMenu" Opened="ContextMenu_Opened">
   <MenuItem Header="Caption" Click="MenuItem_Click" />
</ContextMenu>

然后在最终单击项目时使用

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
{
   var p = Mouse.GetPosition(this);
   var element = this.InputHitTest(p) as FrameworkElement;

   if (element != null)
   {
      //your data object
      ((ContextMenu)sender).DataContext = element.DataContext;
   }
}

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
   var boundObject = ((MenuItem)sender).DataContext;
}

答案 1 :(得分:0)

如果将ContextMenu应用于单个项目,而不是将其应用于ItemsControl本身...:

<UserControl.Resources>
    <ContextMenu x:Key="ContextMenu">
        <MenuItem Header="Caption" Click="MenuItem_Click"></MenuItem>
    </ContextMenu>
</UserControl.Resources>

<ListView x:Name="ListView">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
        </GridView>
    </ListView.View>
</ListView>

...您可以通过PlacementTarget的{​​{1}}获得对数据项的引用。然后,您可以将其投射到ContextMenu上以访问其FrameworkElement

DataContext