【发布时间】:2017-06-14 16:01:35
【问题描述】:
我正在为ListView 中的元素显示上下文菜单。上下文菜单附加到ListView 的TextBlocks 上,如下所示。
<ListView.Resources>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem Command="local:MyCommands.Test" />
</ContextMenu>
<Style TargetType="{x:Type TextBlock}" >
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
</Style>
</ListView.Resources>
上下文菜单正确显示并且 RoutedUIEvent 也被触发。问题是在 Executed 回调中 ExecutedRoutedEventArgs.OriginalSource 是 ListViewItem 而不是 TextBlock。
我尝试设置IsHitTestVisible 属性以及Background(见下文),因为MSDN 说OriginalSource is determined by hit testing
请注意,我使用 GridView 作为 ListView 中的视图。这就是我想要进入 TextBlock(获取列索引)的原因
主窗口
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<ListView>
<ListView.Resources>
<x:Array Type="{x:Type local:Data}" x:Key="Items">
<local:Data Member1="First Item" />
<local:Data Member1="Second Item" />
</x:Array>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem Header="Test" Command="local:MainWindow.Test" />
</ContextMenu>
<Style TargetType="{x:Type TextBlock}" >
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
<Setter Property="IsHitTestVisible" Value="True" />
<Setter Property="Background" Value="Wheat" />
</Style>
</ListView.Resources>
<ListView.ItemsSource>
<StaticResource ResourceKey="Items" />
</ListView.ItemsSource>
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Member1" DisplayMemberBinding="{Binding Member1}"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Window>
MainWindow.xaml.cs
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
namespace WpfApp1
{
public class Data
{
public string Member1 { get; set; }
}
public partial class MainWindow : Window
{
public static RoutedCommand Test = new RoutedCommand();
public MainWindow()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(Test, (s, e) =>
{
Debugger.Break();
}));
}
}
}
【问题讨论】:
-
是的,所以在这种情况下,ListView 项始终具有第一个 hittestvisibility,我不确定,但您可以尝试将
ClickMode="Press"放在TextBlock上,但我不完全确定这会起作用它不继承自 Button 基础,因此保留为注释。 -
如前所述,这是非常自然的,因为该事件实际上最初来自
ListViewItem。您应该重新考虑为什么您认为您需要TextBlock对象。缺少完整的minimal reproducible example,无法给出具体建议。但是您应该能够通过其他方式确定列索引。您不需要深入查看视图结构本身来确定用户单击了什么,因为该信息应该已绑定在 XAML 中并与单击/命令一起发送。 -
@PeterDuniho 你可能是对的,我应该问如何获取该列。 ContextMenu 仅在单击 TextBlock 时显示。如果您在其外部单击,但仍在 ListViewItem 上,则不会显示任何菜单。我假设 TextBlock 不被视为 OriginalSource,因为它缺少使其成为 OriginalSource 候选者的东西
-
@PeterDuniho 我还添加了完整的示例代码
-
感谢您提供的优质样品。如果您可以获得
TextBlock对象,那么您可以更明确地说明如何获得列索引,这将有所帮助。在样本中我仍然不清楚你的期望是什么。
标签: c# wpf xaml routed-events routedeventargs