宇宙仮面の
C# Programming

 
Image

DataGrid (その1)

開発環境: Visual Studio 2003 

次のような機能のForm アプリケーションを作る。
  • データベースに接続しないで直接データソースを使う。
  • 直接セルにデータを入力できる。
  • XMLファイルからデータのセーブ、ロードができる。
Image
注意:
データセット、データテーブルのデータモデルと、データグリッド、カラムスタイルと、ビューとモデルが分離したアーキテクチャになっています。

データセット、データグリッドまわりは、見た目の割りに、関連クラス、インターフェースが非常に複雑なので、注意が必要です。
詳細は.NETのヘルプを参照してください。

作り方

  1. 新しいプロジェクト→ Windows アプリケーションを新規作成。
  2. ツールバーより、データ→DataSet を貼り付ける。すると dataSet1 というインスタンスが作られる。

  3. この dataSet1 のプロパティを開き、Tables コレクションの ...ボタンを押す。
    すると、"テーブル コレクション エディタ"が表示されるので、追加ボタンを押す。すると、Table1 というメンバが追加される。
    TableName は、適当な名前(ここでは、PersonalInfoTable) に変更します。

  4. 次に、この"テーブル コレクション エディタ"の Table1 プロパティより、Columns コレクションの ...ボタンを押す。
    すると、"列 コレクション エディタ"が表示されるので、追加ボタンを押し、Column1, Column2, Column3 と、3つのカラムを追加します。

  5. ここで、Column1-3 のプロパティの ColumnName は、それぞれ適当な名前(ここでは、 ID, Name, Height )とします。

  6. さて、ここまできたら、データセットを表示するためのデータグリッドを貼り付けます。
    ツールバーより MainMenu、DataGrid を貼り付ける。Dock は適当にセットしてください。
  7. さらに、XMLデータのロード、セーブ用に、2つボタンを作る。
  8. ここまでくれば、次のような雛形ができる。
    Image

  9. 次に、データグリッドのプロパティから、DataSource のリストボックスから dataSet1 を選択します。
    すると、次の図のように Form1.cs デザインに□に+マークが表示されるようになります。
    Image

  10. これは、データセットが複数のデータテーブルなどのデータ構造を持てるためで、+を押すことにより、ツリービューのようにデータセット内のデータ構造を表示することができます。
    ためしに、この段階でコンパイルして確かめてみましょう。+を押すと、次のようにデータセットの下に先ほど作った PersonalInfoTable がぶる下がっているのがわかります。
    Image

  11. さらに、PersonalInfo をクリックすると、次のように PersonalInfo が表形式で表示されます。
    Image

  12. さて、これでは見た目が悪いので、11 のように表示されるようにします。
    dataGrid1 のプロパティの DataMember のリストボックスをクリックすると、PersonalInfoTable が現れますので、それを選択します。
    すると、次のように最初から表形式で表示することができます。
    ImageImage

  13. つぎに、データとしての PersonalInfoTable は、ID, Name, Height でもいいのですが、表示は ID、 名前、身長としたい場合や、カラムの幅などのスタイルを変更するには、dataGrid1 のTableStyles コレクションの...ボタンをクリックしてください。すると次のような DataGridTableStyle コレクション エディタが開きます。ここで、追加ボタンを押すと、dataGridTableStyle1 というスタイルを決定するためのインスタンスが生成されます。
    それから、MappingName も選択できるようになってますので、PersonalInfoTable を選択します。(下図)
    注意:
    この MappingName は、スタイルと、実際のデータソースとのマッピングを取るための文字列なので、このMappingName がデータグリッドとデータソース間で一致していないと、正しく表示されません。


    Image

  14. この dataGridTableStyle1 のプロパティから、GridColumnStyle コレクションの ... ボタンを押します。
    すると、DataGridColumStyle コレクション エディタが開きますから、追加ボタンを押してカラム用のスタイルを1つ追加します。
    まずは、このdataGridTextBoxColumn1 のプロパティで、ID のカラムの体裁を整えます。
    MappingName はデータセットとのマッピングをとるためのもので、下図のように選択肢が出てきますから、ID を選択します。
    また、Width, Alighment, HeaderText, NullText などを適当に入力します。
    Image

  15. 同様に、dataGridTextBoxColumn2, dataGridTextBoxColumn3 も次のようにセットします。
    dataGridTextBoxColumn1
    PropertyValue
    MappingNameID
    Width30
    AlignmentLeft
    HeaderText番号
    NullText新規
    dataGridTextBoxColumn2
    PropertyValue
    MappingNameName
    Width100
    AlignmentLeft
    HeaderText名前
    NullText(入力例: 田中 麻希子)
    dataGridTextBoxColumn3
    PropertyValue
    MappingNameHeight
    Width50
    AlignmentRight
    HeaderText身長
    NullText(3桁以下の整数)

  16. ここまでくれば、コンパイルして起動すれば、次のように動作するはずです。
    Image

  17. それぞれXML ファイルからロード、XMLファイルにセーブ用のメソッドを書きます。
    コーディングする必要があるのは、それぞれ10行程度です。前提となる XMLファイルはこのようなフォーマットです。

    Image

  18. XMLファイルからロード
            private void button1_Click(object sender, System.EventArgs e)
            {
                OpenFileDialog dialog = new OpenFileDialog();
                DialogResult result = dialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    // ロードする前に、データセットをクリアする。
                    this.dataSet1.Clear();
                    // データソースに XML のデータを読み込む。
                    FileStream myFileStream = new FileStream(dialog.FileName, System.IO.FileMode.Open);
                    XmlTextReader myXmlReader = new XmlTextReader(myFileStream);
                    // XML ファイルから読み込む
                    this.dataSet1.ReadXml(myXmlReader);   
                    myXmlReader.Close();
                }
            }
  19. XMLファイルにセーブ
            private void button2_Click(object sender, System.EventArgs e)
            {
                SaveFileDialog dialog = new SaveFileDialog();
                DialogResult result = dialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    // データソースに XML のデータを書き込む。
                    FileStream myFileStream = new FileStream(dialog.FileName, System.IO.FileMode.Create);
                    XmlTextWriter myXmlWriter = new XmlTextWriter(myFileStream, System.Text.Encoding.UTF8);
                    // インデントをつけて書き出すように指定する。
                    myXmlWriter.Formatting = Formatting.Indented;
                    // XML ファイルに書き出す
                    this.dataSet1.WriteXml(myXmlWriter);   
                    myXmlWriter.Close();
                }
            }

  20. 以上で、ほとんど Visual Studio .NET でほとんどコーティングなしでできてしまいます。
注意

データグリッドの DataMember がデータセットのテーブルを正しく指定していない場合や、XMLファイルのエレメント名が期待している値でない場合、次のように表示される場合があります。
これは、データセットが複数のデータテーブルなどを持つことができるためで、DataGrid のバグではありません。

データグリッドの DataMemberに表示したいテーブルのエレメント名を指定しているかプロパティエディタで確認してみてください。
Image
日付修正履歴
2002/5/29初期バージョン作成
2002/6/2XML 対応バージョン作成
2002/6/19起動時に表を表示できるように修正
2002/6/22例外処理を追加。データグリッドのキャプション修正。DataMemberまわりを理解しやすいように一部修正。
2002/6/27もっと簡単な作り方があったので、全面書き直し
2002/12/62回ロードしたときにデータがダブってしまう不具合を修正。

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Xml;

namespace DataGrid1
{
    /// <summary>
    /// Form1 の概要の説明です。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Data.DataSet dataSet1;
        private System.Data.DataTable dataTable1;
        private System.Data.DataColumn dataColumn1;
        private System.Data.DataColumn dataColumn2;
        private System.Data.DataColumn dataColumn3;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.DataGrid dataGrid1;
        private System.Windows.Forms.DataGridTableStyle dataGridTableStyle1;
        private System.Windows.Forms.DataGridTextBoxColumn dataGridTextBoxColumn1;
        private System.Windows.Forms.DataGridTextBoxColumn dataGridTextBoxColumn2;
        private System.Windows.Forms.DataGridTextBoxColumn dataGridTextBoxColumn3;
        /// <summary>
        /// 必要なデザイナ変数です。
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Windows フォーム デザイナ サポートに必要です。
            //
            InitializeComponent();

            //
            // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
            //
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

                #region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.dataSet1 = new System.Data.DataSet();
            this.dataTable1 = new System.Data.DataTable();
            this.dataColumn1 = new System.Data.DataColumn();
            this.dataColumn2 = new System.Data.DataColumn();
            this.dataColumn3 = new System.Data.DataColumn();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.dataGrid1 = new System.Windows.Forms.DataGrid();
            this.dataGridTableStyle1 = new System.Windows.Forms.DataGridTableStyle();
            this.dataGridTextBoxColumn1 = new System.Windows.Forms.DataGridTextBoxColumn();
            this.dataGridTextBoxColumn2 = new System.Windows.Forms.DataGridTextBoxColumn();
            this.dataGridTextBoxColumn3 = new System.Windows.Forms.DataGridTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.dataSet1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataTable1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
            this.SuspendLayout();
            // 
            // dataSet1
            // 
            this.dataSet1.DataSetName = "MyDataSet";
            this.dataSet1.Locale = new System.Globalization.CultureInfo("ja-JP");
            this.dataSet1.Tables.AddRange(new System.Data.DataTable[] {
                                                                          this.dataTable1});
            // 
            // dataTable1
            // 
            this.dataTable1.Columns.AddRange(new System.Data.DataColumn[] {
                                                                              this.dataColumn1,
                                                                              this.dataColumn2,
                                                                              this.dataColumn3});
            this.dataTable1.TableName = "PersonalInfoTable";
            // 
            // dataColumn1
            // 
            this.dataColumn1.Caption = "";
            this.dataColumn1.ColumnMapping = System.Data.MappingType.Attribute;
            this.dataColumn1.ColumnName = "ID";
            // 
            // dataColumn2
            // 
            this.dataColumn2.Caption = "";
            this.dataColumn2.ColumnName = "Name";
            // 
            // dataColumn3
            // 
            this.dataColumn3.Caption = "";
            this.dataColumn3.ColumnName = "Height";
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(32, 160);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(104, 40);
            this.button1.TabIndex = 1;
            this.button1.Text = "XMLファイルからロードする";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(208, 160);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(104, 40);
            this.button2.TabIndex = 2;
            this.button2.Text = "XMLファイルにセーブする";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // dataGrid1
            // 
            this.dataGrid1.DataMember = "PersonalInfoTable";
            this.dataGrid1.DataSource = this.dataSet1;
            this.dataGrid1.Dock = System.Windows.Forms.DockStyle.Top;
            this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
            this.dataGrid1.Name = "dataGrid1";
            this.dataGrid1.Size = new System.Drawing.Size(384, 152);
            this.dataGrid1.TabIndex = 3;
            this.dataGrid1.TableStyles.AddRange(new System.Windows.Forms.DataGridTableStyle[] {
                                                                                                  this.dataGridTableStyle1});
            // 
            // dataGridTableStyle1
            // 
            this.dataGridTableStyle1.DataGrid = this.dataGrid1;
            this.dataGridTableStyle1.GridColumnStyles.AddRange(new System.Windows.Forms.DataGridColumnStyle[] {
                                                                                                                  this.dataGridTextBoxColumn1,
                                                                                                                  this.dataGridTextBoxColumn2,
                                                                                                                  this.dataGridTextBoxColumn3});
            this.dataGridTableStyle1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
            this.dataGridTableStyle1.MappingName = "PersonalInfoTable";
            // 
            // dataGridTextBoxColumn1
            // 
            this.dataGridTextBoxColumn1.Alignment = System.Windows.Forms.HorizontalAlignment.Right;
            this.dataGridTextBoxColumn1.Format = "";
            this.dataGridTextBoxColumn1.FormatInfo = null;
            this.dataGridTextBoxColumn1.HeaderText = "番号";
            this.dataGridTextBoxColumn1.MappingName = "ID";
            this.dataGridTextBoxColumn1.NullText = "新規";
            this.dataGridTextBoxColumn1.Width = 50;
            // 
            // dataGridTextBoxColumn2
            // 
            this.dataGridTextBoxColumn2.Format = "";
            this.dataGridTextBoxColumn2.FormatInfo = null;
            this.dataGridTextBoxColumn2.HeaderText = "名前";
            this.dataGridTextBoxColumn2.MappingName = "Name";
            this.dataGridTextBoxColumn2.NullText = "(入力例: 田中 麻希子)";
            this.dataGridTextBoxColumn2.Width = 150;
            // 
            // dataGridTextBoxColumn3
            // 
            this.dataGridTextBoxColumn3.Alignment = System.Windows.Forms.HorizontalAlignment.Right;
            this.dataGridTextBoxColumn3.Format = "";
            this.dataGridTextBoxColumn3.FormatInfo = null;
            this.dataGridTextBoxColumn3.HeaderText = "身長";
            this.dataGridTextBoxColumn3.MappingName = "Height";
            this.dataGridTextBoxColumn3.NullText = "(3桁以下の整数)";
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(384, 222);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.dataGrid1,
                                                                          this.button2,
                                                                          this.button1});
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dataSet1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataTable1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
            this.ResumeLayout(false);

        }
                #endregion

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            // データソースに XML のデータを読み込む。
            FileStream myFileStream = new FileStream(@"C:\Documents and Settings\Uchukamen\デスクトップ\test.xml", System.IO.FileMode.Open);
            XmlTextReader myXmlReader = new XmlTextReader(myFileStream);
            // XML ファイルから読み込む
            this.dataSet1.ReadXml(myXmlReader);   
            myXmlReader.Close();
        }

        private void button2_Click(object sender, System.EventArgs e)
        {
            SaveFileDialog dialog = new SaveFileDialog();
            DialogResult result = dialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                // データソースに XML のデータを書き込む。
                FileStream myFileStream = new FileStream(dialog.FileName, System.IO.FileMode.Create);
                XmlTextWriter myXmlWriter = new XmlTextWriter(myFileStream, System.Text.Encoding.UTF8);
                // インデントをつけて書き出すように指定する。
                myXmlWriter.Formatting = Formatting.Indented;
                // XML ファイルに書き出す
                this.dataSet1.WriteXml(myXmlWriter);   
                myXmlWriter.Close();
            }
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            DialogResult result = dialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                // ロードする前に、データセットをクリアする。
                this.dataSet1.Clear();
                // データソースに XML のデータを読み込む。
                FileStream myFileStream = new FileStream(dialog.FileName, System.IO.FileMode.Open);
                XmlTextReader myXmlReader = new XmlTextReader(myFileStream);
                // XML ファイルから読み込む
                this.dataSet1.ReadXml(myXmlReader);   
                myXmlReader.Close();
            }
        }
    }
}