今回はデータグリッドにコンボボックスを表示したいと思います。
チェックボックスと同様、デフォルトで「DataGridComboBoxColumn」がありますが、
同じ理由(2回クリックしないと変更できない)で「DetaGridTemplateColumn」を利用したいと思います。
プログラムは次の記事のものを流用します。
【WPF】データグリッドにチェックボックスを表示する
※DBはSQLiteに変更してます
StyleDic.xaml
<!-- データグリッド:通常 -->
<Style x:Key="grid-normal" TargetType="DataGrid">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Grid.Row" Value="1" />
<Setter Property="HorizontalScrollBarVisibility" Value="Visible" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="IsReadOnly" Value="False" />
<Setter Property="CanUserAddRows" Value="False"/>
<Setter Property="AlternationCount" Value="1" />
<Setter Property="AlternatingRowBackground" Value="#B2CEEBF7" />
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="VerticalGridLinesBrush" Value="Gray" />
<Setter Property="HorizontalGridLinesBrush" Value="Gray" />
</Style>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Height" Value="25" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" Margin="4,4,4,4" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="dgc-combo" TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Height" Value="25" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" Margin="0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
データグリッドを編集可能(行追加不可)にし、データグリッド内のコンボボックス用定義を追加。
MainWindow.xaml
<Mah:MetroWindow x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
mc:Ignorable="d"
Title="一覧" Height="350" Width="530"
GlowBrush="{DynamicResource AccentColorBrush}"
Icon="/WpfApp1;component/Resource/Cat.ico"
BorderThickness="1"
>
<Window.Resources>
<ResourceDictionary Source="/Style/StyleDic.xaml"/>
</Window.Resources>
<Grid Height="350" Width="530" Margin="0,1,-10,-33">
<Grid.Resources>
<local:KindConverter x:Key="KindConv"/>
</Grid.Resources>
<Rectangle x:Name="rec_overlay" Width="530" Height="330" Style="{StaticResource rec-overlay}" />
<Mah:ProgressRing x:Name="loading_image" Style="{StaticResource pgr-normal}"/>
<Label Content="名前:" Margin="10,10,0,0" Style="{StaticResource lb-normal}"/>
<TextBox x:Name="search_name" Margin="56,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Style="{StaticResource MetroTextBox}"/>
<Label Content="種別:" Margin="201,10,0,0" Style="{StaticResource lb-normal}"/>
<ComboBox x:Name="search_kind" Margin="252,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="125" Style="{StaticResource MetroComboBox}" SelectedIndex="0" />
<Button x:Name="search_button" Content="検索" HorizontalAlignment="Left" Margin="432,12,0,0" VerticalAlignment="Top" Width="75" Click="search_button_Click" Style="{DynamicResource SquareButtonStyle}"/>
<DataGrid Name="dataGrid" HorizontalAlignment="Left" Margin="10,43,0,0" Width="497" Height="225" Style="{StaticResource grid-normal}" >
<DataGrid.Columns>
<DataGridTemplateColumn IsReadOnly="True" Header="選択" Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding No}" ClipboardContentBinding="{x:Null}" Header="No" IsReadOnly="True" Width="40" />
<DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="名前" IsReadOnly="True" Width="80"/>
<DataGridTemplateColumn IsReadOnly="True" Header="性別" CellStyle="{StaticResource dgc-combo}" Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="cmbGender" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.GenderList, Mode=OneWay}"
DisplayMemberPath="Name" SelectedValuePath="Cd" SelectedValue="{Binding Sex}" Width="50"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Age}" ClipboardContentBinding="{x:Null}" Header="年齢" IsReadOnly="True" Width="40"/>
<DataGridTextColumn Binding="{Binding Kind, Converter={StaticResource KindConv}}" ClipboardContentBinding="{x:Null}" Header="種別" IsReadOnly="True" Width="110"/>
<DataGridTextColumn Binding="{Binding Favorite}" ClipboardContentBinding="{x:Null}" Header="好物" IsReadOnly="True" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<Button x:Name="add_button" Content="追加" HorizontalAlignment="Left" Margin="10,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="add_button_Click" Style="{DynamicResource AccentedSquareButtonStyle}"/>
<Button x:Name="upd_button" Content="更新" HorizontalAlignment="Left" Margin="90,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="upd_button_Click" Style="{DynamicResource AccentedSquareButtonStyle}"/>
<Button x:Name="del_button" Content="削除" HorizontalAlignment="Left" Margin="170,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="del_button_Click" Style="{DynamicResource AccentedSquareButtonStyle}"/>
<Button x:Name="imp_button" Content="CSV読込" HorizontalAlignment="Left" Margin="250,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="imp_button_Click" Style="{DynamicResource AccentedSquareButtonStyle}"/>
<Button x:Name="exp_button" Content="CSV出力" HorizontalAlignment="Left" Margin="330,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="exp_button_Click" Style="{DynamicResource AccentedSquareButtonStyle}"/>
<Button x:Name="fld_button" Content="フォルダ参照" HorizontalAlignment="Left" Margin="410,273,0,0" VerticalAlignment="Top" Width="97" Height="30" Click="fld_button_Click" Style="{DynamicResource AccentedSquareButtonStyle}"/>
</Grid>
</Mah:MetroWindow>
「性別」列を「DataGridTemplateColumn」に変更し、コンボボックスを設置。
ポイントは次のプロパティ
ItemsSource
コンボボックスの表示内容となるリスト
コードビハインドにて、DataContextに設定したリストを指定
DisplayMemberPath
バインドされたクラスの表示するメンバーを指定
SelectedValuePath
バインドされたクラスの値となるメンバーを指定
SelectedValue
データグリッドにバインドされたリストのメンバーを指定
この項目が紐付きとなる
コンボボックスに設定するためのクラスを作成
Gender.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace WpfApp1
{
/// <summary>
/// 性別クラス
/// </summary>
public class Gender
{
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="cd"></param>
/// <param name="name"></param>
public Gender(int cd, String name)
{
Cd = cd;
Name = name;
}
/// <summary>
/// 性別コード
/// </summary>
public int Cd { get; set; }
/// <summary>
/// 性別名
/// </summary>
public String Name { get; set; }
}
}
下記をグローバルスコープで定義
MainWindow.xaml.cs(抜粋)
/// <summary>
/// データグリッド:性別コンボの項目リスト
/// </summary>
public List<Gender> GenderList { set; get; }
起動時にデータグリッド内のコンボボックス用リストを作成して設定
MainWindow.xaml.cs(抜粋)
public MainWindow()
{
InitializeComponent();
// データグリッドに表示するコンボの項目を設定
GenderList = new List<Gender>();
GenderList.Add(new Gender(1, "♂"));
GenderList.Add(new Gender(2, "♀"));
this.DataContext = this;
// SampleDb.sqlite を作成(存在しなければ)
using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite"))
{
// データベースに接続
conn.Open();
// コマンドの実行
using (var command = conn.CreateCommand())
{
// テーブルが存在しなければ作成する
// 種別マスタ
StringBuilder sb = new StringBuilder();
sb.Append("CREATE TABLE IF NOT EXISTS MSTKIND (");
sb.Append(" KIND_CD NCHAR NOT NULL");
sb.Append(" , KIND_NAME NVARCHAR");
sb.Append(" , primary key (KIND_CD)");
sb.Append(")");
command.CommandText = sb.ToString();
command.ExecuteNonQuery();
// 猫テーブル
sb.Clear();
sb.Append("CREATE TABLE IF NOT EXISTS TBLCAT (");
sb.Append(" NO INT NOT NULL");
sb.Append(" , NAME NVARCHAR NOT NULL");
sb.Append(" , SEX NVARCHAR NOT NULL");
sb.Append(" , AGE INT DEFAULT 0 NOT NULL");
sb.Append(" , KIND_CD NCHAR DEFAULT 0 NOT NULL");
sb.Append(" , FAVORITE NVARCHAR");
sb.Append(" , primary key (NO)");
sb.Append(")");
command.CommandText = sb.ToString();
command.ExecuteNonQuery();
}
// 種別マスタを取得してコンボボックスに設定する
using (DataContext con = new DataContext(conn))
{
// データを取得
Table<Kind> tblCat = con.GetTable<Kind>();
IQueryable<Kind> result = from x in tblCat orderby x.KindCd select x;
// 最初の要素は「指定なし」とする
Kind empty = new Kind();
empty.KindCd = "";
empty.KindName = "指定なし";
var list = result.ToList();
list.Insert(0, empty);
// コンボボックスに設定
this.search_kind.ItemsSource = list;
this.search_kind.DisplayMemberPath = "KindName";
}
// 切断
conn.Close();
}
}
起動直後、「性別」がコンボボックスになってますね。
クリックすると、コンボボックスが展開されて変更することができます。
データグリッドにコンボボックスを表示する方法は色々ありますが、
とりあえずこんな感じで落ち着きました。
今後他のコントロールも試していきたいと思います。
ではでは。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント