Wpf 在运行时将绑定的ComboBox列添加到DataGridColumn

Wpf 在运行时将绑定的ComboBox列添加到DataGridColumn,wpf,datagrid,combobox,Wpf,Datagrid,Combobox,我想显示一个DataGrid,其中包含我从数据源上传到DataTable中的数据。这些列每次都会不同,有些列需要使用组合框来表示 如何在运行时为需要组合框的列设置DataGridTemplateColumn 好的,这是我在@Meleak的帮助下得到的最接近的结果,几乎在那里,只是在网格未被编辑时显示关键点而不是值 公共部分类主窗口:窗口 { 公共词典MyDictionary{get;set;} public MainWindow() { InitializeComponent();

我想显示一个DataGrid,其中包含我从数据源上传到DataTable中的数据。这些列每次都会不同,有些列需要使用组合框来表示

如何在运行时为需要组合框的列设置DataGridTemplateColumn

好的,这是我在@Meleak的帮助下得到的最接近的结果,几乎在那里,只是在网格未被编辑时显示关键点而不是值

公共部分类主窗口:窗口 { 公共词典MyDictionary{get;set;}

public MainWindow()
{
    InitializeComponent();

    //Init Dictionary
    this.MyDictionary = new Dictionary<int, string>();
    this.MyDictionary.Add(1, "Value 1");
    this.MyDictionary.Add(2, "Value 2");
    this.MyDictionary.Add(3, "Value 3");

    DataTable dt = new DataTable();

    DataColumn column = new DataColumn("MyTypeId", typeof(int));
    dt.Columns.Add(column);

    DataRow newRow = dt.NewRow();
    newRow["MyTypeId"] = 1;

    dt.Rows.Add(newRow);

    dataGrid.Columns.Add(GetNewComboBoxColumn("My Type", "MyTypeId", this.MyDictionary));

    this.DataContext = dt;
}

public static DataGridTemplateColumn GetNewComboBoxColumn(string header,
                                                  string bindingPath,
                                                  object itemsSource)
{
    DataGridTemplateColumn comboBoxColumn = new DataGridTemplateColumn();
    comboBoxColumn.Header = header;

    Binding textBinding = new Binding();
    textBinding.Path = new PropertyPath(bindingPath);

    FrameworkElementFactory textBlock = new FrameworkElementFactory(typeof(TextBlock));
    textBlock.SetValue(TextBlock.MarginProperty, new Thickness(3, 3, 3, 3));
    textBlock.SetBinding(TextBlock.TextProperty, textBinding);

    FrameworkElementFactory comboBox = new FrameworkElementFactory(typeof(ComboBox));
    comboBox.SetValue(ComboBox.MarginProperty, new Thickness(1, 1, 1, 1));
    comboBox.SetBinding(ComboBox.TextProperty, textBinding);
    comboBox.SetValue(ComboBox.SelectedValuePathProperty, "Key");
    comboBox.SetValue(ComboBox.DisplayMemberPathProperty, "Value");

    Binding itemsSourceBinding = new Binding();
    itemsSourceBinding.Source = itemsSource;
    comboBox.SetBinding(ComboBox.ItemsSourceProperty, itemsSourceBinding);

    comboBoxColumn.CellTemplate = new DataTemplate();
    comboBoxColumn.CellTemplate.VisualTree = textBlock;
    comboBoxColumn.CellEditingTemplate = new DataTemplate();
    comboBoxColumn.CellEditingTemplate.VisualTree = comboBox;

    return comboBoxColumn;
}
public主窗口()
{
初始化组件();
//初始字典
this.MyDictionary=新字典();
this.MyDictionary.Add(1,“值1”);
this.MyDictionary.Add(2,“值2”);
这个.MyDictionary.Add(3,“值3”);
DataTable dt=新的DataTable();
DataColumn column=新的DataColumn(“MyTypeId”,typeof(int));
dt.Columns.Add(列);
DataRow newRow=dt.newRow();
newRow[“MyTypeId”]=1;
dt.Rows.Add(newRow);
dataGrid.Columns.Add(getNewcomboxColumn(“我的类型”,“我的类型ID”,this.MyDictionary));
this.DataContext=dt;
}
公共静态DataGridTemplateColumn GetNewComboxColumn(字符串头,
字符串绑定路径,
对象项(源)
{
DataGridTemplateColumn ComboxColumn=新DataGridTemplateColumn();
comboBoxColumn.Header=标题;
Binding textBinding=新绑定();
textBinding.Path=新属性路径(bindingPath);
FrameworkElementFactory textBlock=新FrameworkElementFactory(typeof(textBlock));
textBlock.SetValue(textBlock.MarginProperty,新厚度(3,3,3,3));
textBlock.SetBinding(textBlock.TextProperty,textBinding);
FrameworkElementFactory组合框=新的FrameworkElementFactory(类型(组合框));
comboBox.SetValue(comboBox.MarginProperty,新厚度(1,1,1,1));
comboBox.SetBinding(comboBox.TextProperty,textBinding);
comboBox.SetValue(comboBox.SelectedValuePathProperty,“键”);
comboBox.SetValue(comboBox.DisplayMemberPathProperty,“值”);
Binding itemsSourceBinding=新绑定();
itemsSourceBinding.Source=itemsSource;
comboBox.SetBinding(comboBox.ItemsSourceProperty,itemsSourceBinding);
comboBoxColumn.CellTemplate=新数据模板();
comboBoxColumn.CellTemplate.VisualTree=textBlock;
comboBoxColumn.CellEditingTemplate=新数据模板();
comboBoxColumn.CellEditingTemplate.VisualTree=组合框;
返回comboxcolumn;
}

}更新
您可以使用
DataGridComboxColumn
并设置
SelectedValueBinding
,使其按您想要的方式工作。所以,只要把你的方法改成这个,它就会起作用

public DataGridColumn GetNewComboBoxColumn(string header,
                                           string bindingPath,
                                           object itemsSource)
{
    DataGridComboBoxColumn comboBoxColumn = new DataGridComboBoxColumn();
    comboBoxColumn.Header = header;
    comboBoxColumn.SelectedValuePath = "Key";
    comboBoxColumn.DisplayMemberPath = "Value";

    Binding binding = new Binding();
    binding.Path = new PropertyPath(bindingPath);
    comboBoxColumn.SelectedValueBinding = binding;

    Binding itemsSourceBinding = new Binding();
    itemsSourceBinding.Source = itemsSource;
    BindingOperations.SetBinding(comboBoxColumn, DataGridComboBoxColumn.ItemsSourceProperty, itemsSourceBinding);

    return comboBoxColumn;
}

太好了,我快到了。实际上我有一个绑定到的字典,所以我设置了ComboBox.DisplayMemberPathProperty和ComboBox.SelectedValuePathProperty。但是,my itemsSource仅包含Dictionary键,因此将显示该键(int)。我想要实际显示字典值的内容。我需要更改什么?@openshac:更新了我的答案,并举例说明了如何使用
字典
作为项目
组合框
的资源。梅莱克:谢谢你,这也正是我所拥有的。不幸的是,CellTemplate仍然显示字典的键(int),而不是值(string)。@openshac:当DisplayMemberPath设置为Value时,那么Value就是应该显示的值,所以我无法说出您的问题所在。我可以上传一个工作样本项目为您稍后today@openshac:你的
字典是什么
值类型?源属性应为同一类型。在我的示例中,我使用了字符串。在我看来,
TextBlock
不应该和
字典有任何关系,或者我误解了你的情节?悬赏是为了什么?梅莱克不是已经在帮你了吗?看起来他花了不少力气?!也许他想奖励麦莱克帮助他…,斯蒂芬,那么我鼓励他。只是不太确定在悬赏之前发布的答案是否可以获得悬赏,faq对此并不十分清楚……我相信在悬赏之前发布的答案可以获得,但不会自动获得。希望我没有错。:-)仍然没有一个解决方案,按照原来的问题。正在寻找@Meleak或其他人发布解决原始问题的解决方案。现在已经完成了。