VS2010 WPF(C#) DataGrid + データベース バインド

  DataGrid に MDB のデータを読み込んで表示するテンプレート



SkyDrive へ移動




SQL を作成して、context.ExecuteQuery を実行してバインドします。バインドに必要なクラス( SELECT 構文に対応した表示用のクラス )を用いて、DataGrid には自動的に(DataGrid.AutoGenerateColumns プロパティ)バインドさせます。



  SELECT 構文の列リストの内容と対応するクラス



SQL

  
string cols = "社員コード,氏名,フリガナ,所属,性別," +
	"Format(社員マスタ.作成日, 'yyyy/MM/dd') as 作成日," +
	"Format(社員マスタ.更新日, 'yyyy/MM/dd') as 更新日," +
	"給与,手当,管理者,生年月日";
string query = String.Format(
	"select {0} from 社員マスタ where 社員コード >= '{1}'", cols, "0005"
);
  

バインド用のクラス

  
private class Syain : ItemBaseModel {
	public string 社員コード { get; set; }
	public string 氏名 { get; set; }

	private string _check;
	public string チェック {
		get { return _check; }
		set {
			SetAndNotifyString(GetName(() => チェック), ref _check, value);
		}
	}

	public string フリガナ { get; set; }
	public string 所属 { get; set; }
	public int 性別 { get; set; }
	public string 作成日 { get; set; }
	public string 更新日 { get; set; }
	public int 給与 { get; set; }
	public int? 手当 { get; set; }
	public string 管理者 { get; set; }
	public DateTime? 生年月日 { get; set; }
}
  

テーブル定義(MDB)




作成日と更新日は、変更の発生しない管理用の列なので、SQL 側でフォーマットして、文字列として クラス内で定義しています。生年月日は通常データなので、そのまま日付型として格納していますが、データとしては未入力です。 (DateTime? の ? は NULL許容型です )

SetAndNotifyString は、継承した ItemBaseModel に定義されているバインド時に使うプロパティ変更通知メソッドの実行処理です。

ItemBaseModel

INotifyPropertyChanged インターフェイス

  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Linq.Expressions;

namespace WPF_DataGrid_Database1 {
	public class ItemBaseModel : INotifyPropertyChanged {

		// *********************************************
		// 文字列プロパティ用のセットメソッド
		// *********************************************
		public void SetAndNotifyString(string PropName, 
						ref string OldData,
						string NewData) {
			// 無駄の無いように、値が違った時だけ処理
			if (OldData != NewData) {
				// 値の変更
				OldData = NewData;
				// 値が変更された事をバインドシステムに通知
				NotifyPropertyChanged(PropName);
			}
		}

		// *********************************************
		// プロパティを文字列に変換するメソッド
		// *********************************************
		public string GetName<T>(Expression<Func<T>> e) {
			var member = (MemberExpression)e.Body;
			return member.Member.Name;
		}

		// *****************************************************
		// データが変更された事を通知する為の実装
		// *****************************************************
		public event PropertyChangedEventHandler PropertyChanged;
		public void NotifyPropertyChanged(String propertyName) {
			PropertyChangedEventHandler handler = PropertyChanged;
			if (null != handler) {
				handler(this, new PropertyChangedEventArgs(propertyName));
			}
		}

	}
}
  



  画面定義

画面定義は、一覧表示する為の DataGrid がメインですが、以下のプロパティが重要です。
ItemsSource="{Binding}"
AutoGenerateColumns="True"
IsReadOnly="True"
CanUserAddRows="false"
CanUserDeleteRows="False"
CanUserSortColumns="False"

ItemsSource はバインドする為、本来はコレクション項目を設定するのですが、この場合はコレクションを DataContext に設定するので、{Bibding のみになっています}。

AutoGenerateColumns は、自動的にカラム作成させる設定です。登録済みの既定値は true ですが、省略するとソースコードから判断付きづらいケースもあると考えて True を明示的に設定しています。

IsReadOnly を True に設定する事によって本来編集可能な DataGrid のカラムを問い合わせ用のコントロールとして使うようにしています。

CanUserAddRows="false"
CanUserDeleteRows="False"
CanUserSortColumns="False"


以上の設定は、IsReadOnly を True にした場合でも意図しないコントロールの動作を起こさせない為に設定しています

MainWindow.xaml

  
<Window x:Class="WPF_DataGrid_Database1.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"
	mc:Ignorable="d"
	Title="MainWindow"
	Height="719"
	Width="848"
	BorderBrush="Black"
	BorderThickness="1">
	<Window.Background>
	   <ImageBrush
	      ImageSource="/WPF_DataGrid_Database1;component/Images/back_001.jpg"
	      Stretch="UniformToFill"
	      TileMode="None" />
	</Window.Background>
	
	<Grid
		AllowDrop="True">
		<Grid.RowDefinitions>
			<RowDefinition
				Height="70*" />
			<RowDefinition
				Height="608*" />
		</Grid.RowDefinitions>
		
		<!--実行ボタン-->
		<Button
			Name="actButton"
			Content="データ表示"
			Height="35"
			HorizontalAlignment="Left"
			Margin="28,20,0,0"
			VerticalAlignment="Top"
			Width="154"
			Click="actButton_Click" />

		<!--一覧表示-->
		<DataGrid
			Grid.Row="1"
			Height="534"
			HorizontalAlignment="Left"
			Margin="28,0,0,0"
			Name="dataGrid1"
			VerticalAlignment="Top"
			Width="764"
			Background="#C5FFFFFF"
			
			ItemsSource="{Binding}"
			AutoGenerateColumns="True"
			IsReadOnly="True"
			CanUserAddRows="false"
			CanUserDeleteRows="False"
			CanUserSortColumns="False"
			MouseDoubleClick="dataGrid1_MouseDoubleClick">
		</DataGrid>
		
	</Grid>
</Window>
  



  MainWindow.xaml

殆ど処理は無く、ボタンをクリックした後にデータを読み込んでデータを DataContext に設定しています。一番重要な部分は、ExecuteQuery の結果そのままではバインドできないので、バインド用の ObservableCollection でラップしているところです。後は、DataGrid をダブルクリックした場合の処理ですが、元のクラスのデータの内容を変更するだけで、画面のコントロールに反映されます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Data.Odbc;
using System.Data.Linq;
using System.Data;

namespace WPF_DataGrid_Database1 {
	public partial class MainWindow : Window {

		private OdbcConnection cn = null;
		private ObservableCollection<Syain> syain_list = null;
		// *********************************************
		// コンストラクタ
		// *********************************************
		public MainWindow() {
			InitializeComponent();
		}

		private class Syain : ItemBaseModel {
			public string 社員コード { get; set; }
			public string 氏名 { get; set; }

			private string _check;
			public string チェック {
				get { return _check; }
				set {
					SetAndNotifyString(GetName(() => チェック), ref _check, value);
				}
			}

			public string フリガナ { get; set; }
			public string 所属 { get; set; }
			public int 性別 { get; set; }
			public string 作成日 { get; set; }
			public string 更新日 { get; set; }
			public int 給与 { get; set; }
			public int? 手当 { get; set; }
			public string 管理者 { get; set; }
			public DateTime? 生年月日 { get; set; }
		}

		private void actButton_Click(object sender, RoutedEventArgs e) {

			string cs = null;

			// cs = "Driver={MySQL ODBC 5.2w Driver};" +
			//            "Server=localhost;" +
			//            "Database=lightbox;" +
			//            "Uid=root;" +
			//            "Pwd=password;";

			// *********************************************
			// MDB
			// *********************************************
			cs =
				"Provider=MSDASQL" +
				";Driver={Microsoft Access Driver (*.mdb)}" +
				@";Dbq=lib\販売管理C.mdb" +
				";";

			string cols = "社員コード,氏名,フリガナ,所属,性別," +
				"Format(社員マスタ.作成日, 'yyyy/MM/dd') as 作成日," +
				"Format(社員マスタ.更新日, 'yyyy/MM/dd') as 更新日," +
				"給与,手当,管理者,生年月日";
			string query = String.Format("select {0} from 社員マスタ where 社員コード >= '{1}'", cols, "0005");

			try {
				cn = new OdbcConnection(cs);
				DataContext context = new DataContext(cn);
				syain_list = new ObservableCollection<Syain>(
						context.ExecuteQuery<Syain>(query)
				);
				this.dataGrid1.DataContext = syain_list;
			}
			catch (Exception ex) {
				Debug.WriteLine(ex.Message);
			}

			if (cn.State == ConnectionState.Open) {
				cn.Close();
				cn.Dispose();
			}

		}

		private void dataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
			Debug.WriteLine(dataGrid1.SelectedIndex);
			int row = dataGrid1.SelectedIndex;
			if (row != -1) {
				syain_list[row].チェック = "◎";
			}

		}

	}
}











  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ