使用C#WPF,我有一个对话框,向用户显示带有SQL表名称和DataGrid的ComboBox。在ComboBox中进行选择时,将检索该表的数据并将其动态呈现给DataGrid中的用户。然后,他们可以更改内容,删除行或添加行,并将更改保存回SQL DB。
对于一个特定的表,我想让其中一列成为定义的一组值的ComboBox,这些值当前在枚举中定义。对于该特定表的其他表和其他列,简单的文本字段都可以。
在这里使用了几篇文章,我已经接近了我想要完成的东西,但我遗漏了一些东西(可能非常简单),这使我无法前往我想要的地方。任何帮助,将不胜感激。
我已经创建了一个简单的示例程序来演示我想要完成的内容,并且我在这篇文章中包含了这些代码 - 即我在AutoGenratingColumn上做的是将所需的列更改为ComboBox。我用来做这篇文章的文章是:
Add combobox to datagrid that is linked to a datable
DataGridTemplateColumns, AutoGenerateColumns=true and binding to a DataTable
对于我的示例程序,我只是以编程方式将数据加载到DataTable中,而不是使用DataAdapter来检索值。
在我的示例程序中,我可以显示第二列数据和一个空组合框,下拉列表显示可能的值。但是,未显示初始值,并且未显示或接受所选值。
示例截图为:
我的MainWindow.xaml文件如下:
<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>
我的枚举是:
public enum EnumItems { Item1, Item2 };
public enum ComboItems1 { Item1A, Item1B, Item1C, Item1D };
public enum ComboItems2 { Item2A, Item2B, Item2C, Item2D };
对于示例,我在SelectionChanged和AutoGeneratingColumn上执行以下操作:
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;
}
}
}
答案 0 :(得分:1)
这只是因为枚举和字符串之间的类型转换问题。您可以使用TypeConverter或IValueConverter,但出于演示的目的,最简单的修复方法就是更改:
clm.ItemsSource = Enum.GetValues(typeof(ComboItems1)).Cast<ComboItems1>();
到
clm.ItemsSource = (from System.Enum v in Enum.GetValues(typeof(ComboItems1)) select v.ToString());
即。所以items集合是一组字符串,而不是Enums,然后正确地映射到列类型。