WPF编程实现DataGrid每行不同下拉菜单的DataGridComboBoxColumn绑定问题
如何用代码实现DataGrid每行不同的ComboBox下拉选项?
我最近在做WPF的DataGrid开发,其中要加一列DataGridComboBoxColumn,需求是每行显示不一样的下拉菜单选项。用XAML写的时候这个需求很容易搞定,但换成编程方式创建列的时候,就摸不清怎么正确绑定数据了。我自己试了一段代码,但没达到预期效果:
private DataGridComboBoxColumn CreateComboValueColumn(List<Elements> elements) { DataGridComboBoxColumn column = new DataGridComboBoxColumn(); column.ItemsSource = elements; column.DisplayMemberPath = "Text"; // 这里卡壳了,不知道怎么绑定到每行的数据源让下拉选项不同 }
问题根源
其实你现在的写法是给整个列设置了全局的ItemsSource,所有行都会共享同一个下拉选项集合,自然做不到每行不同。正确的思路是:让每行的ComboBox绑定到当前行数据对象里的专属集合属性,而不是给列设置统一的数据源。
具体实现步骤
先准备好行数据实体类
确保你的DataGrid绑定的数据源(也就是每行对应的实体类)里,有两个关键属性:- 存储当前行下拉选项的集合(比如
RowOptions) - 存储当前选中值的属性(比如
SelectedOption)
举个例子:
public class RowData : INotifyPropertyChanged { private List<Elements> _rowOptions; public List<Elements> RowOptions { get => _rowOptions; set { _rowOptions = value; OnPropertyChanged(); } } private Elements _selectedOption; public Elements SelectedOption { get => _selectedOption; set { _selectedOption = value; OnPropertyChanged(); } } // 实现INotifyPropertyChanged接口的代码 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }这里一定要实现
INotifyPropertyChanged,不然属性变化时UI不会同步更新。- 存储当前行下拉选项的集合(比如
修改代码创建列的逻辑
不要再给列的ItemsSource直接赋值集合,而是通过绑定关联到每行的RowOptions属性,同时把选中项绑定到SelectedOption:private DataGridComboBoxColumn CreateComboValueColumn() { DataGridComboBoxColumn column = new DataGridComboBoxColumn(); // 设置下拉框显示的字段 column.DisplayMemberPath = "Text"; // 绑定下拉选项到当前行的RowOptions属性 column.ItemsSource = new Binding("RowOptions"); // 绑定选中项到当前行的SelectedOption属性 column.SelectedItemBinding = new Binding("SelectedOption"); // 设置列头 column.Header = "自定义选项"; return column; }额外注意事项
- 如果你的
Elements类是引用类型,记得重写Equals和GetHashCode方法,否则WPF可能无法正确识别选中的对象,导致选中项不显示。 - 如果你更倾向于用ID来绑定选中值(而不是直接绑定对象),可以把
SelectedOption换成对应的数据类型(比如int),然后设置SelectedValueBinding和SelectedValuePath:column.SelectedValuePath = "Id"; // Elements类里的ID属性 column.SelectedValueBinding = new Binding("SelectedOptionId"); // RowData里的选中ID属性
- 如果你的
内容的提问来源于stack exchange,提问作者Kajbo
相关产品推荐
相关产品推荐

