C# 在生成的DataGrid中动态使用ComboBox列
使用C#WPF,我有一个对话框,它向用户展示了一个包含SQL表名和DataGrid的组合框。在组合框中进行选择时,将检索该表的数据并将其动态显示给DataGrid中的用户。然后,他们可以更改内容、删除行或添加行,并将更改保存回SQL DB 对于一个特定的表,我想使其中一列成为一组已定义值的组合框,这些值当前在枚举中定义。对于该特定表的其他表和其他列,简单的文本字段就可以了 使用本文中的几篇文章,我已经接近了我想要实现的目标,但是我错过了一些阻碍我实现目标的东西(可能很简单)。任何帮助都将不胜感激 我创建了一个简单的示例程序来演示我试图完成的工作,我在本文中包含了这些代码——即我在AutogeneratingColumn上所做的工作,以将所需的列更改为组合框。到目前为止,我使用的文章有: 对于我的示例程序,我只是以编程方式将数据加载到DataTable中,而不是使用DataAdapter检索值 在我的示例程序中,我可以显示第二列数据和一个空组合框,其中包含显示可能值的下拉列表。但是,不会显示初始值,也不会显示或接受选定值 示例屏幕截图如下: 初始显示: 单击列提供组合框: 所选项目: 移动到另一行: 我的MainWindow.xaml文件如下:C# 在生成的DataGrid中动态使用ComboBox列,c#,wpf,datagrid,C#,Wpf,Datagrid,使用C#WPF,我有一个对话框,它向用户展示了一个包含SQL表名和DataGrid的组合框。在组合框中进行选择时,将检索该表的数据并将其动态显示给DataGrid中的用户。然后,他们可以更改内容、删除行或添加行,并将更改保存回SQL DB 对于一个特定的表,我想使其中一列成为一组已定义值的组合框,这些值当前在枚举中定义。对于该特定表的其他表和其他列,简单的文本字段就可以了 使用本文中的几篇文章,我已经接近了我想要实现的目标,但是我错过了一些阻碍我实现目标的东西(可能很简单)。任何帮助都将不胜感激
<Window x:Class="DGridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:DGridTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ObjectDataProvider x:Key="EnumData" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:EnumItems"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="Enum1" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:ComboItems1"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="Enum2" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:ComboItems2"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<DataGrid x:Name="dgrid1" Margin="10,37,10.4,10.4" AutoGeneratingColumn="dgrid1_AutoGeneratingColumn">
<DataGrid.Columns>
</DataGrid.Columns>
</DataGrid>
<ComboBox x:Name="combo1" HorizontalAlignment="Left" DataContext="{Binding Source={StaticResource EnumData}}" ItemsSource="{Binding Mode=OneWay}" Margin="10,10,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="combo1_SelectionChanged"/>
</Grid>
</Window>
对于示例,我在SelectionChanged和AutoGenerating列上执行以下操作:
private void combo1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
dgrid1.ItemsSource = null;
dgrid1.Items.Clear();
if (dataTable != null)
{
dataTable.Dispose();
dataTable = null;
}
dataTable = new DataTable("dt");
if (dataTable != null)
{
dataTable.Columns.Add("Col1", typeof(string));
dataTable.Columns.Add("Col2", typeof(string));
if (combo1.SelectedValue.ToString() == "Item1")
{
DataRow row = dataTable.NewRow();
row["Col1"] = ComboItems1.Item1B.ToString();
row["Col2"] = "Item Text : " + ComboItems1.Item1B.ToString();
dataTable.Rows.Add(row);
row = dataTable.NewRow();
row["Col1"] = ComboItems1.Item1A.ToString();
row["Col2"] = "Item Text : " + ComboItems1.Item1A.ToString();
dataTable.Rows.Add(row);
row = dataTable.NewRow();
row["Col1"] = ComboItems1.Item1D.ToString();
row["Col2"] = "Item Text : " + ComboItems1.Item1D.ToString();
dataTable.Rows.Add(row);
}
else
{
DataRow row = dataTable.NewRow();
row["Col1"] = ComboItems2.Item2D.ToString();
row["Col2"] = "Item Text : " + ComboItems2.Item2D.ToString();
dataTable.Rows.Add(row);
row = dataTable.NewRow();
row["Col1"] = ComboItems2.Item2B.ToString();
row["Col2"] = "Item Text : " + ComboItems2.Item2B.ToString();
dataTable.Rows.Add(row);
row = dataTable.NewRow();
row["Col1"] = ComboItems2.Item2A.ToString();
row["Col2"] = "Item Text : " + ComboItems2.Item2A.ToString();
dataTable.Rows.Add(row);
}
dgrid1.ItemsSource = dataTable.DefaultView;
}
}
AutoGeneratingColumn--保留对DisplayMemberPath和SelectedValuePath的引用,这些引用在前面的一个链接中被引用:
private void dgrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (combo1.SelectedIndex == (int)EnumItems.Item1)
{
if (e.PropertyName == "Col1")
{
DataGridComboBoxColumn clm = new DataGridComboBoxColumn();
clm.Header = e.PropertyName;
clm.ItemsSource = Enum.GetValues(typeof(ComboItems1)).Cast<ComboItems1>();
//clm.DisplayMemberPath = "Col1";
//clm.SelectedValuePath = "Col1";
clm.SelectedValueBinding = new Binding("Col1"); ;
e.Column = clm;
}
}
}
private void dgrid1_AutoGeneratingColumn(对象发送方,DataGridAutoGeneratingColumnEventArgs e)
{
if(combo1.SelectedIndex==(int)EnumItems.Item1)
{
如果(e.PropertyName==“Col1”)
{
DataGridComboxColumn clm=新DataGridComboxColumn();
clm.Header=e.PropertyName;
clm.ItemsSource=Enum.GetValues(typeof(ComboItems1)).Cast();
//clm.DisplayMemberPath=“Col1”;
//clm.SelectedValuePath=“Col1”;
clm.SelectedValueBinding=新绑定(“Col1”);
e、 列=clm;
}
}
}
这只是因为枚举和字符串之间存在类型转换问题。您可以使用TypeConverter或IValueConverter,但就演示而言,最简单的修复方法就是更改:
clm.ItemsSource = Enum.GetValues(typeof(ComboItems1)).Cast<ComboItems1>();
i、 e.因此items集合是一组字符串,而不是枚举,ahich然后正确映射到列类型。这解决了问题,看起来更好。谢谢关于如何使ComboBox始终可见,而不仅仅是在单元格内单击“编辑条目”时可见,您有什么想法吗?要实现这一点,我认为您必须使用DataGridTemplateColumn和包含ComboBox的模板,而不是DataGridComboBoxColumn。
clm.ItemsSource = Enum.GetValues(typeof(ComboItems1)).Cast<ComboItems1>();
clm.ItemsSource = (from System.Enum v in Enum.GetValues(typeof(ComboItems1)) select v.ToString());