在生成的DataGrid

时间:2016-12-06 21:18:01

标签: c# wpf datagrid

使用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来检索值。

在我的示例程序中,我可以显示第二列数据和一个空组合框,下拉列表显示可能的值。但是,未显示初始值,并且未显示或接受所选值。

示例截图为:

初始显示:

单击列提供ComboBox:

选择的项目:

转到另一行:

我的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;

        }
    }
}

1 个答案:

答案 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,然后正确地映射到列类型。