And*_*ech 19 c# wpf xaml contextmenu
我有以下内容GridView:
<ListView Name="TrackListView" ItemContainerStyle="{StaticResource itemstyle}">
<ListView.View>
<GridView>
<GridViewColumn Header="Title" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Artist" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Artist.Name}" />
<GridViewColumn Header="Album" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Name}"/>
<GridViewColumn Header="Length" Width="100" HeaderTemplate="{StaticResource BlueHeader}"/>
</GridView>
</ListView.View>
</ListView>
Run Code Online (Sandbox Code Playgroud)
现在,我想在右边的有界项目上显示一个上下文菜单,这将允许我在后面的代码中处理事件时检索所选项目.
我可以通过哪种方式实现这一目标?
[更新]
按照Dennis Roche的代码,我现在有了这个:
<ListView Name="TrackListView" ItemContainerStyle="{StaticResource itemstyle}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnListViewItem_PreviewMouseLeftButtonDown" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add to Playlist"></MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Title" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Artist" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Artist.Name}" />
<GridViewColumn Header="Album" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Name}"/>
<GridViewColumn Header="Length" Width="100" HeaderTemplate="{StaticResource BlueHeader}"/>
</GridView>
</ListView.View>
</ListView>
Run Code Online (Sandbox Code Playgroud)
但是在运行时,我收到了这个例外:
无法将"System.Windows.Controls.ContextMenu"类型的内容添加到"System.Object"类型的对象中.标记文件'MusicRepo_Importer; component/controls/trackgridcontrol.xaml'中对象'System.Windows.Controls.ContextMenu'出错.
问题是什么?
Den*_*nis 20
是的,使用上下文菜单添加ListView.ItemContainerStyle.
<ListView>
<ListView.Resources>
<ContextMenu x:Key="ItemContextMenu">
...
</ContextMenu>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnListViewItem_PreviewMouseLeftButtonDown" />
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Run Code Online (Sandbox Code Playgroud)
注意:您需要将ContextMenu作为资源引用,并且无法在本地定义它.
这将启用整行的上下文菜单.:)
另请参阅我处理PreviewMouseLeftButtonDown事件,以便我可以确保项目是聚焦的(当您查询ListView时,它是当前选定的项目).我发现在改变应用程序之间的焦点时我不得不这样做,在你的情况下可能不是这样.
更新
在代码隐藏文件中,您需要向上移动可视树以查找列表容器项,因为事件的原始源可以是项模板的元素(例如,堆栈面板).
void OnListViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.Handled)
return;
ListViewItem item = MyVisualTreeHelper.FindParent<ListViewItem>((DependencyObject)e.OriginalSource);
if (item == null)
return;
if (item.Focusable && !item.IsFocused)
item.Focus();
}
Run Code Online (Sandbox Code Playgroud)
的MyVisualTreeHelper是使用我已经写了快速走可视化树的包装.下面张贴了一个子集.
public static class MyVisualTreeHelper
{
static bool AlwaysTrue<T>(T obj) { return true; }
/// <summary>
/// Finds a parent of a given item on the visual tree. If the element is a ContentElement or FrameworkElement
/// it will use the logical tree to jump the gap.
/// If not matching item can be found, a null reference is returned.
/// </summary>
/// <typeparam name="T">The type of the element to be found</typeparam>
/// <param name="child">A direct or indirect child of the wanted item.</param>
/// <returns>The first parent item that matches the submitted type parameter. If not matching item can be found, a null reference is returned.</returns>
public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
return FindParent<T>(child, AlwaysTrue<T>);
}
public static T FindParent<T>(DependencyObject child, Predicate<T> predicate) where T : DependencyObject
{
DependencyObject parent = GetParent(child);
if (parent == null)
return null;
// check if the parent matches the type and predicate we're looking for
if ((parent is T) && (predicate((T)parent)))
return parent as T;
else
return FindParent<T>(parent);
}
static DependencyObject GetParent(DependencyObject child)
{
DependencyObject parent = null;
if (child is Visual || child is Visual3D)
parent = VisualTreeHelper.GetParent(child);
// if fails to find a parent via the visual tree, try to logical tree.
return parent ?? LogicalTreeHelper.GetParent(child);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这些额外信息有所帮助.
丹尼斯
丹尼斯,
喜欢这个例子,但是我没有找到你的Visual Tree Helper的任何需求......
<ListView.Resources>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem x:Name="menuItem_CopyUsername"
Click="menuItem_CopyUsername_Click"
Header="Copy Username">
<MenuItem.Icon>
<Image Source="/mypgm;component/Images/Copy.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem x:Name="menuItem_CopyPassword"
Click="menuItem_CopyPassword_Click"
Header="Copy Password">
<MenuItem.Icon>
<Image Source="/mypgm;component/Images/addclip.png" />
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem x:Name="menuItem_DeleteCreds"
Click="menuItem_DeleteCreds_Click"
Header="Delete">
<MenuItem.Icon>
<Image Source="/mypgm;component/Images/Delete.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
</Style>
</ListView.ItemContainerStyle>
Run Code Online (Sandbox Code Playgroud)
然后在MenuItem_Click事件中添加了如下所示的代码:
private void menuItem_CopyUsername_Click(object sender, RoutedEventArgs e)
{
Clipboard.SetText(mySelectedItem.Username);
}
Run Code Online (Sandbox Code Playgroud)
mySelectedItem用于ListView.SelectedItem:
<ListView x:Name="ListViewCreds" SelectedItem="{Binding mySelectedItem, UpdateSourceTrigger=PropertyChanged}" ....
Run Code Online (Sandbox Code Playgroud)
如果它有帮助,请打勾我
| 归档时间: |
|
| 查看次数: |
31259 次 |
| 最近记录: |