データグリッドビューを動的に切り替えてみる |
データグリッドビューの表示内容を変えてみます。
【サンプルを作成した環境】
・WindowsForms
・.NetFramework 4.0
※VisualStudio C# 2010 Express使用
「-ALL-」では「TestA」と「TestB」をまとめて表示します。
「-ALL-」は行の追加不可(編集はOK)、
「TestA」と「TestB」は行の追加可能です。
「TestA」と「TestB」で行の追加されると
「-ALL-」でも表示されるようになります。
クラス図はこんな感じです。
今回のポイントは以下のとおりです。
・コレクションはBindingListを使用して
双方向バインドを行います。
・BindingList#ListChangedイベントを使って
「-ALL-」用リストに行追加などを反映しています。
ではソースです。
ViewModels(リスト内の要素)
namespace MultiDataGrid.ViewModels
{
/// <summary>
/// スーパークラス
/// </summary>
public class TestBase
{
public int ID { set; get; }
public string Name { set; get; }
/// <summary>
/// コピー元のグリッドのRowIndexを格納する
/// </summary>
private int refIndex;
/// <summary>
/// コピー元のグリッドのRowIndexを返す
/// </summary>
/// <returns>グリッドのRowIndex</returns>
public int GetRefIndex()
{
return this.refIndex;
}
/// <summary>
/// コピー元のグリッドのRowIndexを格納する
/// </summary>
/// <param name="index"></param>
public void SetRefIndex(int index)
{
this.refIndex = index;
}
}
/// <summary>
/// サブクラスA
/// </summary>
public class TestA:TestBase
{
public string ValueA { set; get; }
public string ValueA1 { set; get; }
}
/// <summary>
/// サブクラスB
/// </summary>
public class TestB : TestBase
{
public string ValueB { set; get; }
}
}
フォーム
※コンボボックス(comboBox1)とデータグリッドビュー(dataGridView1)をフォームに配置してください。
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using MultiDataGrid.ViewModels;
namespace MultiDataGrid
{
/// <summary>
/// サンプルフォーム
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// コンボボックス「-ALL-」選択時に表示するリスト
/// </summary>
/// <remarks>testAListとtestBListをマージしたリスト</remarks>
private BindingList<TestBase> testBaseList = new BindingList<TestBase>();
/// <summary>
/// コンボボックス「TestA」選択時に表示するリスト
/// </summary>
private BindingList<TestA> testAList = new BindingList<TestA>();
/// <summary>
/// コンボボックス「TestB」選択時に表示するリスト
/// </summary>
private BindingList<TestB> testBList = new BindingList<TestB>();
/// <summary>
/// コンストラクタ
/// </summary>
public Form1()
{
InitializeComponent();
//コンボボックスの選択項目を作成
this.comboBox1.Items.Add("-ALL-");
this.comboBox1.Items.Add("TestA");
this.comboBox1.Items.Add("TestB");
//コンボボックス選択変更時のイベント処理
this.comboBox1.SelectedIndexChanged += (sender, e) =>
{
this.dataGridView1.SuspendLayout();
switch (this.comboBox1.SelectedItem.ToString())
{
case "-ALL-":
//追加不可
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.DataSource = this.testBaseList;
break;
case "TestA":
//追加可能
this.dataGridView1.AllowUserToAddRows = true;
this.dataGridView1.DataSource = this.testAList;
break;
case "TestB":
//追加可能
this.dataGridView1.AllowUserToAddRows = true;
this.dataGridView1.DataSource = this.testBList;
break;
}
this.dataGridView1.ResumeLayout();
};
//BindingListのリスト変更イベントを設定
this.testAList.ListChanged += this.ListChanged;
this.testBList.ListChanged += this.ListChanged;
//ダミーデータを追加
this.testAList.Add(new TestA() { ID = 1, Name = "TestA1", ValueA = "va1", ValueA1 = "va1-1" });
this.testAList.Add(new TestA() { ID = 3, Name = "TestA2", ValueA = "va2", ValueA1 = "va2-1" });
this.testBList.Add(new TestB() { ID = 2, Name = "TestB1", ValueB = "vb1" });
}
/// <summary>
/// BindingListのリスト変更イベント
/// </summary>
/// <param name="sender">対象リスト</param>
/// <param name="e">変更情報</param>
/// <remarks>testBaseList(-ALL-)への追加・削除処理を実装</remarks>
private void ListChanged(object sender, ListChangedEventArgs e)
{
//追加処理
if (e.ListChangedType == ListChangedType.ItemAdded)
{
var bindingList = sender as dynamic;
var instance = bindingList[e.NewIndex] as TestBase;
//現在表示中の対象リストの行番号をインスタンスに格納
instance.SetRefIndex(e.NewIndex);
//testBaseList(-ALL-)に追加
this.testBaseList.Add(instance);
}
//削除処理
if (e.ListChangedType == ListChangedType.ItemDeleted)
{
var bindingList = sender as dynamic;
//削除対象オブジェクトは存在しない(削除した行番号だけしかない)ので
//リスト内の要素の型を取得する
var senderType = bindingList.GetType().BaseType.GetGenericArguments()[0];
//同じ型でなおかつ当時の行番号が存在するインスタンスを抽出する
var q = this.testBaseList.Where(row => row.GetRefIndex() == e.NewIndex &&
row.GetType().Equals(senderType));
if (q.Any())
{
//インスタンスが存在していれば、それを削除する
this.testBaseList.Remove(q.Single());
}
}
}
}
}
参考になれば幸いです。
よかったらクリックしてください。
にほんブログ村