C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

TemplateFieldの動的追加について /Yammaer (21/09/19(Sun) 00:50) #98113
Re[1]: TemplateFieldの動的追加について /WebSurfer (21/09/19(Sun) 09:23) #98114
│└ Re[2]: TemplateFieldの動的追加について /Yammaer (21/09/19(Sun) 17:56) #98116
│  └ Re[3]: TemplateFieldの動的追加について /WebSurfer (21/09/20(Mon) 11:10) #98118
│    └ Re[4]: TemplateFieldの動的追加について /Yammaer (21/09/24(Fri) 10:31) #98141
Re[1]: TemplateFieldの動的追加について /ポテロングしお味 (21/09/19(Sun) 16:39) #98115
  ├ Re[2]: TemplateFieldの動的追加について /Yammaer (21/09/19(Sun) 18:03) #98117
  │└ Re[3]: TemplateFieldの動的追加について /WebSurfer (21/09/21(Tue) 20:36) #98119
  └ Re[2]: TemplateFieldの動的追加について /Yammaer (21/09/24(Fri) 10:46) #98142
    └ Re[3]: TemplateFieldの動的追加について /Yammaer (21/09/24(Fri) 10:55) #98143


親記事 / ▼[ 98114 ] ▼[ 98115 ]
■98113 / 親階層)  TemplateFieldの動的追加について
□投稿者/ Yammaer (1回)-(2021/09/19(Sun) 00:50:32)

分類:[ASP.NET (VB)] 

初めまして。
Yammaerと申します。

Asp.net(VB.net)のTemplateFieldの動的追加について質問があります。

今回、どうしても、TemplateFieldを動的に追加する必要があり、
以下のAspxのコードと同様のTemplateFieldをVB.netのコードで作成したいです。
Aspx
<asp:TemplateField >
    <ItemTemplate>
        <asp:Label ID="lblSyoruiName" runat="server" Text='<%# Bind("SyoruiName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

いろいろ調べ、以下までは作成できたのですが、データバインドの部分がどう記述して良いかわかりません。
(バインドするDataTableは事前の処理にて作成済です。)

VB.net
Private Sub FieldADD()
    Dim TField As New TemplateField

    TField.ItemTemplate = New MyItemTemplate()

    GridView1.Columns.Add(TField)

End Sub

Class MyItemTemplate
    Implements ITemplate

    Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
            Implements System.Web.UI.ITemplate.InstantiateIn

        Dim lblSyoruiName As New Label

        lblSyoruiName.ID = "lblSyoruiName"

        container.Controls.Add(lblSyoruiName)

    End Sub


いろいろなサイトなので、検索し、試してみましたが、うまく行きませんでした。
皆様のお知恵を拝借できれば、幸いでございます。
よろしくお願い致します。



[ □ Tree ] 返信 編集キー/

▲[ 98113 ] / ▼[ 98116 ]
■98114 / 1階層)  Re[1]: TemplateFieldの動的追加について
□投稿者/ WebSurfer (2347回)-(2021/09/19(Sun) 09:23:32)
No98113 (Yammaer さん) に返信

> いろいろ調べ、以下までは作成できたのですが、データバインドの部分がどう記述して良いかわかりません。
> (バインドするDataTableは事前の処理にて作成済です。)

何に列を追加したのか、どのタイミングで追加したのかという重要な情報が書いてないってことを
自覚してますか?

もし GridView なら、その RowDataBound イベントのハンドラで当該 Label を探して、その Text
プロパティにデータを書き込むことを考えてはいかが。

タイミングの問題があるので可能かどうかは分かりませんが、考えてみてください。

あと、XY 問題になっているかもしれないので、質問には Y だけでなく X も書くことをお勧めします。
[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98114 ] / ▼[ 98118 ]
■98116 / 2階層)  Re[2]: TemplateFieldの動的追加について
□投稿者/ Yammaer (2回)-(2021/09/19(Sun) 17:56:09)
No98114 (WebSurfer さん) に返信
いろいろ、失礼いたしました。

列についてですが、GridViewです。
GridViewで条件を指定し、ボタンを押下したタイミングでGridViewを表示させようと
しております。

元はBoundFieldでしたが、機能の拡張をしたく、TemplateFieldになりました。
今回の上記ではLableコントロールですが、実際はLabelコントロールとCheckBoxコントロールを
使用する予定です。

RowDataBound イベントで値をテキストに直接する方法も最終手段として考えておりますが、
出来れば、元のソースをできるだけ生かすことと、経験も兼ねて、データバインドでできればと思って
おります。

よろしくお願いいたします。
[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98116 ] / ▼[ 98141 ]
■98118 / 3階層)  Re[3]: TemplateFieldの動的追加について
□投稿者/ WebSurfer (2348回)-(2021/09/20(Mon) 11:10:43)
No98116 (Yammaer さん) に返信

> 今回の上記ではLableコントロールですが、実際はLabelコントロールとCheckBoxコントロールを
> 使用する予定です。
> 
> RowDataBound イベントで値をテキストに直接する方法も最終手段として考えておりますが、
> 出来れば、元のソースをできるだけ生かすことと、経験も兼ねて、データバインドでできればと思って
> おります。

昔、Microsoft の VS2008 の MSDN ライブラリに「方法 : DataList Web サーバー コントロール
のテンプレートを動的に作成する 」というのがあって(今はネットには見つからない)、その方法
が GridView にも使えます。

質問に書いてあった ITemplate インターフェイスを継承してなんちゃらというプリミティブことを
する必要はなくて、以下の手順で簡単に TemplateField を追加できます。

(1) テンプレートの中身のコントロールを配置したユーザーコントロール (.ascx) を作成する。

質問者さんは「LabelコントロールとCheckBoxコントロール」とのことなので以下のようにします。
下の例ではユーザーコントロールの名前は NewTemplate.ascx.cs としています。データバインド式
も含めることができます。質問者さんのケースでは "ProductName" ではなく "SyoruiName" になる
のでしょうか。

<%@ Control Language="C#" AutoEventWireup="true" 
    CodeBehind="NewTemplate.ascx.cs" Inherits="WebApplication2.NewTemplate" %>

<asp:CheckBox ID="CheckBox1" runat="server" />

<asp:Label ID="Label1" runat="server" Text='<%# Eval("ProductName") %>'></asp:Label>

(2) TemplateField を生成、Page.LoadTemplate メソッドで (1) の .ascx を ItemTemplate
にロードした上で GridView の列に追加。

その .aspx と .aspx.cs のコードは以下のようになります。

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" 
    AutoEventWireup="true" CodeBehind="LoadTemplate.aspx.cs" 
    Inherits="WebApplication2.LoadTemplate" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <h1>GridView</h1>
    <asp:SqlDataSource ID="SqlDataSource1" 
        runat="server" 
        ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" 
        SelectCommand="SELECT TOP 10 [ProductID], [ProductName], [UnitPrice] FROM [Products]">
    </asp:SqlDataSource>

    <asp:GridView ID="GridView1" 
        runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" 
        DataSourceID="SqlDataSource1">
        <Columns>
            <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
                InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
            <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
                SortExpression="UnitPrice" />
        </Columns>
    </asp:GridView>
</asp:Content>


using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{
    public partial class LoadTemplate : System.Web.UI.Page
    {
        protected void Page_Init(object sender, EventArgs e)
        {
            var templateField = new TemplateField();
            templateField.ItemTemplate = Page.LoadTemplate("NewTemplate.ascx");
            templateField.HeaderText = "動的に追加した ItemTemplate";
            GridView1.Columns.Add(templateField);
        }
    }
}

[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98118 ] / 返信無し
■98141 / 4階層)  Re[4]: TemplateFieldの動的追加について
□投稿者/ Yammaer (5回)-(2021/09/24(Fri) 10:31:05)
No98118 (WebSurfer さん) に返信
連絡が遅くなり申し訳ありません。

こちらの都合になりますが、色々と立て込んでおり、先程、書き込みを
拝見しました。
申し訳ありません。

ご教授いただいた件ですが、今回はポテロングしお味様の投稿で対応させていただきましたが、
自分のレベルアップも兼ねて、テストで色々と使ってみようと思います。
ありがとうございました。

また、私の投稿の内容の不備でご迷惑をおかけしておりますが、
自作自演ではございませので、ご理解いただければ幸いでございます。

技術的なことや、書込みの前提なことも勉強になりました。
色々とお力添えありがとうございました。


[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98113 ] / ▼[ 98117 ] ▼[ 98142 ]
■98115 / 1階層)  Re[1]: TemplateFieldの動的追加について
□投稿者/ ポテロングしお味 (1回)-(2021/09/19(Sun) 16:39:21)
No98113 (Yammaer さん) に返信

こんな感じ

Class MyItemTemplate
    Implements ITemplate

    Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
            Implements System.Web.UI.ITemplate.InstantiateIn

        Dim lblSyoruiName As New Label
        lblSyoruiName.ID = "lblSyoruiName"
        AddHandler lblSyoruiName.DataBinding, AddressOf lblSyoruiName_DataBind
        
        container.Controls.Add(lblSyoruiName)

    End Sub

    Sub lblSyoruiName_DataBind(sender As Object, e As EventArgs)
        Dim label = DirectCast(sender, Label)
        Dim container = DirectCast(label.BindingContainer, IDataItemContainer)
        label.Text = Convert.ToString(DataBinder.Eval(container.DataItem, "SyoruiName"), CultureInfo.CurrentCulture)
    End Sub

End Class

[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98115 ] / ▼[ 98119 ]
■98117 / 2階層)  Re[2]: TemplateFieldの動的追加について
□投稿者/ Yammaer (3回)-(2021/09/19(Sun) 18:03:42)
No98115 (ポテロングしお味 さん) に返信
ありがとうございます!!
まさしく、このことをずっと調べておりました。
コーディングまでしていただき、わかりやすいです。

今日、明日は休日のため、対応できませんが、
明後日、試しに対応してみます。

いろいろ、探してて、正直、疲れ果てていました。。。
本当に涙がこぼれそうなくらい感動&感謝しております。

本当にありがとうごさいました。


[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98117 ] / 返信無し
■98119 / 3階層)  Re[3]: TemplateFieldの動的追加について
□投稿者/ WebSurfer (2349回)-(2021/09/21(Tue) 20:36:36)
自作自演だったのか・・・
[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98115 ] / ▼[ 98143 ]
■98142 / 2階層)  Re[2]: TemplateFieldの動的追加について
□投稿者/ Yammaer (6回)-(2021/09/24(Fri) 10:46:41)
No98115 (ポテロングしお味 さん) に返信
報告が遅くなり、大変申し訳ありません。

その後、ご教授していただいた方法にて無事、作成できました。
また、同様にチェックボックスを追加しまたがこちらも試行錯誤して
うまくいきました。

正直、この件が解決できなかったら、HTMLのテーブルを使用して、
地道に一つ一つ作成することも考えておりましたので、本当に助かりました。

本当にありがとうございました。

[ 親 98113 / □ Tree ] 返信 編集キー/

▲[ 98142 ] / 返信無し
■98143 / 3階層)  Re[3]: TemplateFieldの動的追加について
□投稿者/ Yammaer (7回)-(2021/09/24(Fri) 10:55:04)
今後、私と似たようなかたが出るかもしれませんので、
当方にて気づいた点を書込みさせていただきます。

・テンプレートフィールドに動的に追加したコントロールはポストバック時に消えてしまうため、
 Page_Loadイベントなどで都度、再作成が必要になります。


・テンプレートフィールドに動的に追加したコントロールにイベントを付与(?)したい場合は以下のような
 方法で実現可能です。
私は上記の再作成後に以下を追加しました。
For Each gvRow As GridViewRow In GridView.Rows
chkXxxx = gvRow.FindControl("chkXxxx")
AddHandler chkXxxx.CheckedChanged, New EventHandler(AddressOf chkXxxx_CheckedChanged)

 Next

[ 親 98113 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -