我有一个标准的WPF< DataGrid>具有特定列(即不自动生成)。它通过将ItemsSource设置为具有各种属性的对象列表填充在C#中,并且数据网格中的各个列通过XAML中的Binding =“{Binding XXX}”绑定到相应的属性。
现在,我想在用户右键单击单元格时显示上下文菜单,但菜单内容应根据用户单击的单元格而有所不同。我无法弄清楚如何做到这一点,所以任何建议都将不胜感激。
理想情况是给定列中的每个单元格(不是列标题)将具有相同的上下文菜单,并且不同的列将具有不同的上下文菜单。如果菜单中的某些项目不适用于该特定行,则它们可能会显示为灰色。菜单的内容可以根据用户点击的列进行硬编码,但是我必须有某种动态机制(理想情况下通过C#函数,而不是无限的XAML)来决定何时灰显菜单物品,什么时候不去。
编辑:我可以使用一个解决方案,让我在菜单出现时动态添加菜单项(在C#代码中),如果我可以告诉它出现的是哪个单元格。其实我更喜欢这样的事情,因为我比CAM更喜欢C#。
答案 0 :(得分:1)
以下是完整的示例:
VM:
public class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<Employee> Employees { get; set; }
public RelayCommand<Employee> FireCommand { get; set; }
private Employee selectedEmployee;
public Employee SelectedEmployee
{
get { return selectedEmployee; }
set
{
if (value != selectedEmployee)
{
selectedEmployee = value;
PropertyChanged(this, new PropertyChangedEventArgs("SelectedEmployee"));
FireCommand.RaiseCanExecuteChanged();
}
}
}
public MainViewModel()
{
Employees = new ObservableCollection<Employee>
{
new Employee{ Name = "Mickey Mouse", CanBeFired = true },
new Employee{ Name = "Barack Obama", CanBeFired = true },
new Employee{ Name = "Chuck Norris", CanBeFired = false /* Don't even try!!! */ }
};
foreach (Employee e in Employees)
{
e.PropertyChanged += (s, a) =>
{
if (a.PropertyName == "CanBeFired")
{
FireCommand.RaiseCanExecuteChanged();
}
};
}
FireCommand = new RelayCommand<Employee>(_ => Employees.Remove(SelectedEmployee), _ => SelectedEmployee != null && SelectedEmployee.CanBeFired);
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
XAML:
<DataGrid ItemsSource="{Binding Employees}" SelectedValue="{Binding SelectedEmployee}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Binding="{Binding CanBeFired,UpdateSourceTrigger=PropertyChanged}"></DataGridCheckBoxColumn>
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Fire" Command="{Binding FireCommand}">
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
请注意,您不需要泛型RelayCommand
,因此您可以忽略lambda的泛型参数和_
参数。