更新时间:2022-10-21 09:53:09
您可以使用上下文菜单作为资源吗?
类似:
< UserControl.Resources>
< ContextMenu x:name =contextMenuExampleDataContext ={Binding Path = PlacementTarget,RelativeSource = {RelativeSource Self}}
< MenuItem Header =Show Selected
Command ={Binding Path = DataContext.RemoveStudentCommand}
CommandParameter ={Binding Path = SelectedItem}/>
< / ContextMenu>
< /UserControl.Resources>
然后在列表上,执行以下操作:
< Listbox ContextMenu = {StaticResource contextMenuExample} ... />
或者你真的想使用ItemContainerStyle吗?
从 - > 如何右键单击列表框中的项目并打开WPF上的菜单
< ListBox Name =someListBoxMouseDown =someListBox_MouseDown>
< ListBox.Resources>
<! - 定义一个上下文菜单 - >
< ContextMenu x:Key =MyElementMenu>
< MenuItem Header =DeleteClick =MenuItemDelete_Click/>
< / ContextMenu>
<! - 为当前ListBox中的每个ListBoxItem设置一个上下文菜单 - >
< Style TargetType ={x:Type ListBoxItem}>
< Setter Property =ContextMenuValue ={StaticResource MyElementMenu}/>
< / Style>
< /ListBox.Resources>
< ListBoxItem> ...< / ListBoxItem>
< ListBoxItem> ...< / ListBoxItem>
< ListBoxItem> ...< / ListBoxItem>
< / ListBox>
In WPF, with MVVM light, there's a Class
(which is consist of some students), and the Class
hold some Student
s.
Right-Click one Student's name, then will show a MessageBox
, it is ok in this way:
ClassDetailView.xaml
<UserControl DataContext="{Binding ClassDetail, Source={StaticResource Locator}}">
<DockPanel>
<ListBox
ItemsSource="{Binding Students}"
DisplayMemberPath="Name">
<ListBox.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem
Header="Show Selected"
Command="{Binding Path=DataContext.RemoveStudentCommand}"
CommandParameter="{Binding Path=SelectedItem}"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
</DockPanel>
</UserControl>
But, it don't work in this way (use ListBox.ItemContainerStyle):
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Show Selected"
Command="{Binding Path=DataContext.RemoveStudentCommand}"
CommandParameter="{Binding Path=SelectedItem}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
instead of
<ListBox.ContextMenu>
<ContextMenu ...>
...
<ContextMenu />
</ListBox.ContextMenu>
ClassDetailViewModel.cs
namespace ContextMenu.ViewModel
{
public class ClassDetailViewModel : ViewModelBase
{
public ClassDetailViewModel()
{
CreateData();
}
public void CreateData()
{
students.Add(new StudentViewModel() { Name = "QQ" });
students.Add(new StudentViewModel() { Name = "WW" });
students.Add(new StudentViewModel() { Name = "EE" });
students.Add(new StudentViewModel() { Name = "RR" });
students.Add(new StudentViewModel() { Name = "AA" });
students.Add(new StudentViewModel() { Name = "SS" });
students.Add(new StudentViewModel() { Name = "DD" });
students.Add(new StudentViewModel() { Name = "FF" });
students.Add(new StudentViewModel() { Name = "ZZ" });
students.Add(new StudentViewModel() { Name = "XX" });
}
public const string StudentsPropertyName = "Students";
private ObservableCollection<StudentViewModel> students =
new ObservableCollection<StudentViewModel>();
public ObservableCollection<StudentViewModel> Students
{
get { return students; }
set
{
if (students == value) { return; }
students = value;
RaisePropertyChanged(StudentsPropertyName);
}
}
private RelayCommand<StudentViewModel> removeStudentCommand;
public RelayCommand<StudentViewModel> RemoveStudentCommand
{
get
{
return removeStudentCommand
?? (removeStudentCommand =
new RelayCommand<StudentViewModel>(ExecuteRemoveStudentCommand));
}
}
private void ExecuteRemoveStudentCommand(StudentViewModel student)
{
if (null == student) { return; }
MessageBox.Show(string.Format("RemoveStudent:{0}", student.Name));
}
}
}
StudentViewModel.cs
namespace ContextMenu.ViewModel
{
public class StudentViewModel : ViewModelBase
{
public const string NamePropertyName = "Name";
private string name = "";
public string Name
{
get { return name; }
set
{
if (name == value) { return; }
name = value;
RaisePropertyChanged(NamePropertyName);
}
}
}
}
Can you use the contextmenu as a resource?
Something like:
<UserControl.Resources>
<ContextMenu x:name="contextMenuExample" DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Show Selected"
Command="{Binding Path=DataContext.RemoveStudentCommand}"
CommandParameter="{Binding Path=SelectedItem}"/>
</ContextMenu>
</UserControl.Resources>
Then on list, do something like:
<Listbox ContextMenu = {StaticResource contextMenuExample} ... />
Or do you really want to use ItemContainerStyle?
from -> how to right click on item from Listbox and open menu on WPF
<ListBox Name="someListBox" MouseDown="someListBox_MouseDown">
<ListBox.Resources>
<!--Defines a context menu-->
<ContextMenu x:Key="MyElementMenu">
<MenuItem Header="Delete" Click="MenuItemDelete_Click"/>
</ContextMenu>
<!--Sets a context menu for each ListBoxItem in the current ListBox-->
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContextMenu" Value="{StaticResource MyElementMenu}"/>
</Style>
</ListBox.Resources>
<ListBoxItem>...</ListBoxItem>
<ListBoxItem>...</ListBoxItem>
<ListBoxItem>...</ListBoxItem>
</ListBox>