Wpf 将ListViewItem ContextMenu MenuItem命令绑定到ListView的ViewModel';s项目来源
我有一个Wpf 将ListViewItem ContextMenu MenuItem命令绑定到ListView的ViewModel';s项目来源,wpf,listview,mvvm,data-binding,binding,Wpf,Listview,Mvvm,Data Binding,Binding,我有一个扩展器的列表视图。每个扩展器(表示数据库表)将在另一个列表视图中包含其下的项。我想右键单击并在最里面的项上有一个“编辑”选项,这些项表示相应数据库表中的记录 在myMainEditorViewModel中有一个名为“Edit”的ICommand。此命令所在的Datacontext与最外层名为“TestGroupsListView”的ListView的Datacontext相同 下面是Expander列表视图的XAML标记。我为通过菜单项绑定的元素名在绑定中引用而命名的最外层列表视图:
扩展器的列表视图
。每个扩展器
(表示数据库表)将在另一个列表视图
中包含其下的项。我想右键单击并在最里面的项上有一个“编辑”选项,这些项表示相应数据库表中的记录
在myMainEditorViewModel
中有一个名为“Edit”的ICommand
。此命令所在的Datacontext与最外层名为“TestGroupsListView”的ListView的Datacontext相同
下面是Expander列表视图的XAML标记。我为通过菜单项绑定的元素名在绑定中引用而命名的最外层列表视图:
<ListView Name="TestGroupsListView" ItemsSource="{Binding TestGroups}" Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<Expander Style="{StaticResource MaterialDesignExpander}" >
<Expander.Header>
<Grid MaxHeight="50">
<TextBlock Text="{Binding Name}"/>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Add..." Command="{Binding Add}"/>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</Expander.Header>
<ListView ItemsSource="{Binding Records}" Style="{StaticResource MaterialDesignListView}" Margin="30 0 0 0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Edit"
Command="{Binding ElementName=TestGroupsListView, Path=DataContext.Edit}"
CommandParameter="{Binding }"/>
</ContextMenu>
</Grid.ContextMenu>
<Button Content="{Binding RecordName}" Command="{Binding ElementName=TestGroupsListView, Path=DataContext.Edit}"/>
<!--<TextBlock Text="{Binding RecordName}" AllowDrop="True"/>-->
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我能够成功地将DataTemplate中的按钮绑定到“编辑”,但当我尝试将菜单项的命令
绑定到“编辑”时,什么也没有发生。为什么按钮命令绑定可以使用ElementName
工作,而ContextMenu
中的相同绑定不能工作?我认为最好对ListView全局使用上下文菜单,对每个子ListView全局使用上下文菜单。好的,这是我的解决方案:
<ListBox ItemsSource="{Binding Groups}">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Add..." Command="{Binding Add}"/>
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<Expander Header="{Binding Name}">
<ListView ItemsSource="{Binding Records}" SelectedItem="{Binding SelectedRecord}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Edit" Command="{Binding Edit}" IsEnabled="{Binding CanEdit}"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
为了更好地理解代码隐藏:
public class GroupsVM : ViewModelBase
{
public ICommand Add
{
get => null; //Command implementation
}
public ObservableCollection<GroupVM> Groups { get; set; } = new ObservableCollection<GroupVM>()
{
new GroupVM { Name = "First" },
new GroupVM { Name = "Second" },
new GroupVM { Name = "Third" }
};
}
public class GroupVM : ViewModelBase
{
private string _name;
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
public ICommand Edit
{
get => null; //Command implementation
}
public bool CanEdit => SelectedRecord != null;
public ObservableCollection<RecordVM> Records { get; set; } = new ObservableCollection<RecordVM>()
{
new RecordVM { Name="Record1" },
new RecordVM { Name="Record2" },
new RecordVM { Name="Record3" }
};
private RecordVM _selectedRecord = null;
public RecordVM SelectedRecord
{
get => _selectedRecord;
set
{
_selectedRecord = value;
OnPropertyChanged();
OnPropertyChanged("CanEdit");
}
}
}
public class RecordVM : ViewModelBase
{
private string _name;
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
}
public类GroupsVM:ViewModelBase
{
公共ICommand添加
{
get=>null;//命令实现
}
公共ObservableCollection组{get;set;}=new ObservableCollection()
{
新的GroupVM{Name=“First”},
新的GroupVM{Name=“Second”},
新的GroupVM{Name=“Third”}
};
}
公共类GroupVM:ViewModelBase
{
私有字符串\u名称;
公共字符串名
{
get=>\u name;
设置{u name=value;OnPropertyChanged();}
}
公共ICommand编辑
{
get=>null;//命令实现
}
public bool CanEdit=>SelectedRecord!=null;
公共ObservableCollection记录{get;set;}=new ObservableCollection()
{
新的RecordVM{Name=“Record1”},
新的RecordVM{Name=“Record2”},
新记录VM{Name=“Record3”}
};
私有记录vm_selectedRecord=null;
公共记录VM SelectedRecord
{
get=>\u selectedRecord;
设置
{
_selectedRecord=值;
OnPropertyChanged();
不动产变更(“CanEdit”);
}
}
}
公共类RecordVM:ViewModelBase
{
私有字符串\u名称;
公共字符串名
{
get=>\u name;
设置{u name=value;OnPropertyChanged();}
}
}
谢谢!我喜欢为每一位都有一个单独的视图模型,一个用于测试组,一个用于记录。我差点就吃到了,但这种方式对我来说很有意义。