- PR -

DataGrid列の動的生成について

1
投稿者投稿内容
勘助
会議室デビュー日: 2002/11/10
投稿数: 14
投稿日時: 2002-11-10 17:03
こんにちは、XXXXです。

現在ソースコードにてWeb画面に貼り付けたDataGridに対し動的に列を作成しようとしております。DataGridでは実行時に自動的に列を生成をOFFにしてます。
コード内でBoundColumnオブジェクトを作成して各種プロパティに適切な値を設定した後
DataGridのカラムコレクションに追加して画面に表示させております。
この方法は統一されたDataSourceに対し必要なカラムだけ表示できるので便利だと思っているのですが、これをTemplateColumnでも同じようにやりたいのです。
==>現在出来なくて困っていること・・・
1.TemplateColumnオブジェクトを生成した後で、ラベルやテキストボックスなどのコントロールを追加したいが出来ない。(デザイナであれば貼り付けるだけですが・・・)
2.「1」ができたら、追加したラベルのTextプロパティに対しデータバインディングできるように設定したい。
==>まで
上記問題が解決できれば一画面上で、リクエストに応じて動的にDataGridを変化させることができます。
現在の解決策としては、別ページであらかじめ画面に定義しておく方法。または、同一ページ内でデザイナであらかじめカラムを作成しておいて、リクエストに応じてカラム表示/非表示を制御しております。当然非表示カラムにはバインドしてもしょうがないのでしないように制御もしております。

何か解決できる策がございますでしょうか?
るーく
会議室デビュー日: 2002/02/22
投稿数: 4
投稿日時: 2002-11-12 20:39
こんなものを作っておいて、
Class MyTemplate : Implements ITemplate
Public Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn
Dim description As Label = New Label()
AddHandler description.DataBinding, AddressOf Me.BindDescription
container.Controls.Add(description)
End Sub

Public Sub BindDescription(ByVal sender As Object, ByVal e As EventArgs)
Dim lbl As Label = CType(sender, Label)
Dim container As DataGridItem = CType(lbl.NamingContainer, DataGridItem)
lbl.Text = CType(container.DataItem("FIELD_NAME"), String)
End Sub
End Class

こんな感じでどうでしょうか?

Dim objTemplateColumn As TemplateColumn = New TemplateColumn()
objTemplateColumn.ItemTemplate = New MyTemplate()
勘助
会議室デビュー日: 2002/11/10
投稿数: 14
投稿日時: 2002-11-12 22:46
返信ありがとうございます。
使用言語を記述しなく申し訳ありませんでした。C#を使用しております。
以下のように書き換えましたがエラーが一杯でて動作できない状態です。
*****
public class MyTemplate:ITemplate
{

public ITemplate.InstantiateIn InstantiateIn(Control container)
{
Label description = new Label();
System.EventHandler.CreateDelegate   (description.DataBinding,this.BindDescription);
container.Controls.Add(description);
}
public void BindDescription(Object sender, EventArgs e)
{
Label lbl = (Label)sender;
DataGridItem container = (DataGridItem)lbl.NamingContainer;
lbl.Text = (String)(container.DataItem("FIELD_NAME"));
}
}
*****
最初のメソッド「ITemplate.InstantiateIn」でエラーがでております。
調べたところ、これはメソッドみたいですね?
C#ではどのように書き直せばよいかお分かりでしたら、差し支えなければサンプル
ソースを教えていただけないでしょうか?

それとこのクラスを汎用的に使用するとすればコンストラクタを定義して
作成したいコントロールオブジェクト「例:TextBoxやLabel」を引き渡せば
可能でしょうか?現状ではLabelコントロール固定ですよね・・・。

誠に申し訳ありませんが、よろしくお願いいたします。

るーく
会議室デビュー日: 2002/02/22
投稿数: 4
投稿日時: 2002-11-13 01:25
http://www.dotnet247.com/247reference/a.aspx?u=http://msdn.microsoft.com/msdnmag/issues/02/01/cutting/cutting0201.asp

↑に載ってますね。
こんな感じですかね。

コード:
public class WebForm1 : System.Web.UI.Page
{
	protected System.Web.UI.WebControls.DataGrid MyDataGrid;

	class MyTemplate : ITemplate
	{
		public void InstantiateIn(Control container) 
		{
			Label lblName = new Label();
			lblName.DataBinding += new EventHandler(this.BindName);
			container.Controls.Add(lblName);
		}

		void BindName(Object sender, EventArgs e)
		{
			Label l = (Label) sender;
			DataGridItem container;
			container = (DataGridItem) l.NamingContainer;

			DataRowView drv;
			drv = ((DataRowView) container.DataItem);
			l.Text = drv["StringValue"].ToString();
		}
	}

	private void Page_Load(object sender, System.EventArgs e)
	{
		// ページを初期化するユーザー コードをここに挿入します。

		DataGridColumnCollection objDataGridColumnCollection = MyDataGrid.Columns;
		TemplateColumn objTemplateColumn = new TemplateColumn();
		objTemplateColumn.ItemTemplate = new MyTemplate();
		objDataGridColumnCollection.Add(objTemplateColumn);

		MyDataGrid.DataSource = CreateDataSource();
		MyDataGrid.DataBind();

	}

	ICollection CreateDataSource() 
	{
		DataTable dt = new DataTable();
		DataRow dr;

		dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
		dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
		dt.Columns.Add(new DataColumn("DateTimeValue", typeof(DateTime)));
		dt.Columns.Add(new DataColumn("BoolValue", typeof(bool)));
		dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double)));

		for (int i = 0; i < 9; i++) 
		{
			dr = dt.NewRow();

			dr[0] = i;
			dr[1] = "Item " + i.ToString();
			dr[2] = DateTime.Now;
			dr[3] = (i % 2 != 0) ? true : false;
			dr[4] = 1.23 * (i+1);

			dt.Rows.Add(dr);
		}

		DataView dv = new DataView(dt);
		return dv;
	}
}

勘助
会議室デビュー日: 2002/11/10
投稿数: 14
投稿日時: 2002-11-17 23:25
るーくさん、ありがとうございました。

動的に作成したカラムはPostBack時にViewStateで維持されないのですね?
単に画面上ボタンを貼り付けてPostBackを発生するようにして
Page_Load()では(!IsPostBack)でポストバック時は何もしないように
したら動的に作成したカラムは消えてしまいました。
もともとデザインで指定したBoundColumnは消えないのに動的に作成したItemTemplateColumn
は消えちゃうっていうのはなんででしょうかね?

色々ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)