有一个WPF MVVM应用程序。在主视图上,我有一个元素列表,这些元素是用ListView.ItemTemplate
定义的,因为我想有一个带有删除操作的上下文菜单。
其Command
与视图分离,并保存在ViewModel DreamListingViewModel 中。
问题是,在单击Delete时,我无法让它在ViewModelk上执行命令,因为上下文是项目的上下文,而不是项目容器的上下文。
我可以通过将上下文菜单定义移到列表视图元素之外来使其工作,但是当我打开上下文菜单时,它会 Flink ,好像它被调用了“20”次(我认为确实发生了,因为我在集合中有元素),无论如何,我需要一个干净的解决方案,我对XAML非常不好。
以下是我的视图外观:
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="0 5 0 5" Background="Transparent" Width="auto">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding DeleteSelectedDream}"
CommandParameter="{Binding DeleteSelectedDream,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type viewmodels:DreamListingViewModel}}}"
/>
</ContextMenu>
</Grid.ContextMenu>
...
它是主窗口,在App.cs的通用主机中初始化:
public partial class App : Application
{
private readonly IHost _host;
public App()
{
...
_host = Host.CreateDefaultBuilder().ConfigureServices(services =>
{
...
services.AddTransient<DreamListingViewModel>();
services.AddSingleton((s) => new DreamListingView()
{
DataContext = s.GetRequiredService<DreamListingViewModel>()
});
...
}).Build();
Command和CommandParameter值是我一直在尝试的,但它不起作用
下面是我的ViewModel的外观:
internal class DreamListingViewModel : ViewModelBase
{
public ICommand DeleteSelectedDream{ get; }
...
最后,当命令被触发时,我需要传递显示菜单的当前元素。
所以,这是我想要的:
1.用户用鼠标右键点击列表项- OK
1.看到带有删除条目- OK的菜单
1.点击“删除”后,将当前梦想(列表中的项目)作为参数- ERR,激发命令DeleteSelectedDream
3条答案
按热度按时间thigvfpy1#
您的示例缺少必要的信息,但我会尽力提供帮助。
首先,你需要验证你是否真的绑定到了你的视图模型。你使用的是Prism还是标准的WPF?在你的视图代码隐藏的构造函数中,为你的VM示例设置 DataContext。
现在,您通过Mode 'FindAncestor'绑定到一个相对源,AncestorType被设置为视图模型的类型。这通常不起作用,因为视图模型并不是WPF视图的“可视化树”的一部分。也许您的ItemTemplate以某种方式将其连接起来。在我的一个大型WPF应用程序中,我使用Telerik UI for WPF和类似的方法,然而,我将上下文菜单的 DataContext 设置为 RelativeSource(设置为 Self)和 Path(设置为 PlacementTarget.DataContext)。
在我的例子中,你不必使用所有的XAML,只要观察我是怎么做的。用“ContextMenu”替换“RadContextMenu”,忽略挪威语单词-在这里,只使用你需要的:
在您的示例中,它将是:
现在,我认为您正在使用类 ListViewItemhttps://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.listviewitem?view=netframework-4.8。您可能需要在此处指定DataContext.DeleteSelectedDream,以确保绑定到ICommand实现所在的DataContext。
pbpqsu0x2#
意外地发现this的答案,这基本上是我所需要的,只是添加到它的
CommandParameter
发送项目,它的工作原理就像魔术!moiiocjp3#
我认为以下是最简单的;也许是因为我不理解WPF,但它“简单”好记,而且它可以与我的MVVM模式一起工作。
MyViewModelXXXXXXX命名项位于Map到控件的数据上下文的视图模型中。