2016-12-06 25 views
1

C#WPFを使用すると、SQLテーブル名とDataGridのComboBox付きのユーザーを表示するダイアログが表示されます。 ComboBoxで選択すると、そのテーブルのデータが取得され、DataGridのユーザーに動的に表示されます。次に、内容を変更したり、行を削除したり、行を追加したり、変更をSQL DBに保存したりすることができます。生成されたDataGridでComboBox列を動的に使用する

特定のテーブルでは、列の1つを現在列挙型で定義されている定義済みの値セットのComboBoxにしたいと考えています。他のテーブルとその特定のテーブルの他の列については、単純なテキストフィールドは問題ありません。

ここでいくつかの記事を使用して私は達成しようとしているものに近づいていますが、私は何かになりたくない(おそらく非常に単純な)ものがありません。どんな助けもありがとう。

私は何を達成しようとしているのかを実証するための簡単なサンプルプログラムを作成しました。この記事では、このコードをAutoGenratingColumnでComboBoxに変更しています。私はこれを取得するために使用されている記事は遠く離れている:私のサンプルプログラムについては

DataGridTemplateColumns, AutoGenerateColumns=true and binding to a DataTable

Add combobox to datagrid that is linked to a datable

が、私はただのDataTableにプログラム的にデータをロードするのではなく値を取得するためのDataAdapterを使用しています。

私のサンプルプログラムでは、データの2番目の列とドロップダウンで可能な値を示す空のコンボボックスを表示できます。ただし、初期値は表示されておらず、選択された値は表示されていません。

サンプルスクリーンショットは、次のとおり

初期表示:

項目が選択:

移動別の行に:

マイメインウィンドウ

クリック列がコンボボックスを提供.xamlファイルは次のとおりですS:

<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

これは、列挙型と列挙型の間の型変換の問題が原因です。あなたはのTypeConverterまたはIValueConverterを使用することができますが、あなたのデモの目的のために最も簡単な修正は、単に変更することです:

clm.ItemsSource = Enum.GetValues(typeof(ComboItems1)).Cast<ComboItems1>(); 

すなわち

clm.ItemsSource = (from System.Enum v in Enum.GetValues(typeof(ComboItems1)) select v.ToString()); 

にアイテムのコレクションは、文字列のセットですので、ありません列挙型は、列型に正しくマッピングされます。

+0

問題を解決したように見えます。ありがとう。 ComboBoxをセル内をクリックして「エントリを編集」するのではなく、いつでも見ることができるようにするためのアイデアはありますか? –

+0

これを実現するには、DataGridComboBoxColumnではなくComboBoxを含むテンプレートでDataGridTemplateColumnを使用する必要があると思います。 –