質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

6616閲覧

ASP.NETのWebフォームから動的にユーザ―コントロールを呼び出したい

coco0303

総合スコア1

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2020/09/07 02:22

編集2020/09/07 07:23

前提・実現したいこと

ASP.NETにて動的に呼び出すユーザ―コントロールを変更したいと思っております。
理由としてはサイト構築の手法についての方針が、
IISでURLパーマをかけてすべてのrequestが、Default.aspxで受け取ります。

URL

1例: 2http://abc.com → http://abc.com 3http://abc.com/123/233 → http//:abc.com?s1=123&s2=233

通常は、

asp

1<%@ Register Tagprefix = "win" Tagname="NaviHeader" Src="~/123.ascx" %>

などで宣言して画面配置先に

asp

1<win:NaviHeader id="navi" runat="Server" />

で配置されると思いますが

今回は、送信されてくるGET値によりユーザ―コントロールをを呼び出す手段
Src=の部分を、~/123.ascx だったり ~/321.ascx だったりと変更したいと思っております。

asp

1<%@ Register Tagprefix = "win" Tagname="NaviHeader" Src="~/123.ascx" %>

開発管理、保守管理上追加したい要件。

  • ロード時に今回の処理に必要な情報のみを初期化、設定したい
  • Default.aspxから読み込む情報は

 デザインコーディングのためにビジュアルスタジオのGUIを利用を想定
デザイン・処理ごとにファイルを分けたい

  • 読み込む各ユーザーコントロールにはそれぞれの処理が存在するが、

 Default.aspxにも基本的な処理・共通の処理が入ると思う。

情報お待ちしております。

試したこと

1.宣言時にIF文で試してみる。

asp

1<% If Request.QueryString("so") = "123" Then %> 2<%@ Register Tagprefix = "win" Tagname="NaviHeader" Src="~/123.ascx" %> 3<% Else %> 4<%@ Register Tagprefix = "win" Tagname="NaviHeader" Src="~/321.ascx" %> 5<% End If %>

asp

12.宣言部分を変数にしてみる。 2<%@ Register Tagprefix = "win" Tagname="NaviHeader" Src="~/" & Request.QueryString("so1") & ".ascx" %>

3.以下のサイトを参考にユーザ―コントロールを変数にしてみる。
ユーザーコントロールを動的に生成する
リンク内容

ascxに以下の記述を入れて

asp

1<%@ Register Tagprefix = "win" Tagname="NaviHeader" Src="~/123.ascx" %> 2<win:NaviHeader id="navi" runat="Server" />

ascx.vbのLoadイベントに以下を追記

vb

1 Dim uc As UserControl 2 If Request.Item("so1") = "login" Then 3 uc = Page.LoadControl("login.ascx") 4 ElseIf Request.Item("so1") = "login2" Then 5 uc = Page.LoadControl("login2.ascx") 6 Else 7 uc = Page.LoadControl("login2.ascx") 8 End If 9 navi = uc

###現状のソース

asp

1<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %> 2<%@ Import Namespace="System.Data" %> 3<%@ Import Namespace="System.Data.SqlClient" %> 4 5<% If Request.QueryString("so") = "123" Then %> 6<%@ Register Tagprefix = "win1" Tagname="NaviHeader" Src="~/123.ascx" %> 7<% Else %> 8<%@ Register Tagprefix = "win2" Tagname="NaviHeader" Src="~/321.ascx" %> 9<% End If %> 10 11<!DOCTYPE html> 12<html lang="ja"> 13 <head> 14<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 15 <meta charset="utf-8" /> 16 <title><% = DateTime.Now.Year %></title> 17 </head> 18 <body> 19 <form runat="Server"> 20 <!--メインコンテンツ--> 21 <win1:NaviHeader id="navi" runat="Server" /> 22  <win2:NaviHeader id="navi" runat="Server" /> 23 </form> 24 </body> 25</html> 26 27

Default.aspx.vb(初期表示状態)

VB

1Partial Class _Default 2 Inherits System.Web.UI.Page 3 Private Sub _Default_Load(sender As Object, e As EventArgs) Handles Me.Load 4 5 End Sub 6End Class

###現状の結果
‘‘‘asp
<% If Request.QueryString("so") = "123" Then %>
<%@ Register Tagprefix = "win1" Tagname="NaviHeader" Src="/123.ascx" %>
<% Else %>
<%@ Register Tagprefix = "win2" Tagname="NaviHeader" Src="
/321.ascx" %>
<% End If %>
‘‘‘
のIF文がまったく動作せず
"/123.ascx"の内容、"/321.ascx"の内容が両方書き出されています。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5 <meta charset="utf-8" /> 6 <title>2020</title> 7 </head> 8 <body> 9 <form runat="Server"> 10 <!--メインコンテンツ--> 11 123<!--123.ascxの内容--> 12 321<!--321.ascxの内容--> 13 </form> 14 </body> 15</html>

###もしかしたらできないことなのかも。
以下のサイトを見ていて
ASP.NET ページのページはどこから派生しているか?
リンク内容
Default.aspx→Default.aspx.vbの順番で処理させるとのことで記述がありました。
そのため、簡単ではないのかと想像してしました。

補足情報(FW/ツールのバージョンなど)

FW:4.6.2
win:10
IIS
VB
ビジュアルスタジオ2015

質問を見ていただきありがとうございます。
お分かりになる方いらっしゃいましたらよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/07 04:58 編集

コードは ``` と ``` で囲ってください(``` はバッククォート 3 つ)。インデントされて見やすくなるので。インデントされてないコードは質問者さん自身も読む気がしないのでは? 参考にしたサイトは、その URL の文字列を記載するだけでなく、それからリンクを張ってください。
退会済みユーザー

退会済みユーザー

2020/09/07 04:56

現状のコードではどのような結果になるのでしょう? その結果と期待した動作とはどのように違うのでしょう?
退会済みユーザー

退会済みユーザー

2020/09/07 05:05

ユーザーコントロールを使うのは必須なのですか? 異なるログイン画面のようなものを複数のユーザーコントロールにして状況に応じて使い分けたいということのように思えますが、であれば、もっと簡単に、ユーザーコントロールなどは使わないで、複数 Panel を配置してそれに異なるログイン画面を配置し、Panel を切り替えた方がよさそうだと思いますけど。
coco0303

2020/09/07 06:21

SurferOnWwwさま。 サイトに質問させてもらいのに不慣れで、ご指摘ありがとうございました。 本来は、各ページより共通で利用できるユーザーコントロールを呼び出すのが普通と思いますが。 現状数は見えないのですがDefault.aspxから呼び出すユーザーパネルは50-200になると思います。
coco0303

2020/09/07 06:27

現状調べたところ・・・ コンパイルの順番的に、読込、処理順番的に、難しいのかもと思ってきました。
退会済みユーザー

退会済みユーザー

2020/09/07 06:34 編集

現状のコードではどのような結果になるのでしょう? その結果と期待した動作とはどのように違うのでしょう? ・・・に対する答えはいかがですか? > ユーザーパネルは50-200になると思います。 使用予定のユーザーコントロールが 50 - 200 ぐらいで非常に多いので Panel を切り替えるという案は NG と言っていますか? > コンパイルの順番的に、読込、処理順番的に、難しいのかもと思ってきました。 どういうことでしょう? 意味がわかりません。
coco0303

2020/09/07 07:08

失礼いたしました。 > 現状のコードではどのような結果になるのでしょう? 現状は。 ‘‘‘asp <% If Request.QueryString("so") = "123" Then %> <%@ Register Tagprefix = "win1" Tagname="NaviHeader" Src="~/123.ascx" %> <% Else %> <%@ Register Tagprefix = "win2" Tagname="NaviHeader" Src="~/321.ascx" %> <% End If %> ‘‘‘ のIF文がまったく動作せず "~/123.ascx"の内容、"~/321.ascx"の内容が両方書き出されています。 >Panel を切り替えのご提案について 技術検証ができていないので何とも言えないところはあるのですが ご提案の手法についていくつかの課題が思いつきました。 1.ロード時に50-200のパネルの初期表示のための配置デザインコントロールの初期化やDBアクセスなどが必要になり重くなってしまうのでは? 2.コードが一つのファイルにつくられてしまうのは避けたいので各パネルのデザイン・処理ごとにファイルを分けたいが可能だろうか? 2-1.ファイルを分けて作った時に、デザインコーディングのためにビジュアルスタジオのGUIを利用を続けることは可能だろうか? 3.ASPの処理の順番について 以下のサイトを見ていて ASP.NET ページのページはどこから派生しているか? https://aspnet.keicode.com/aspnet/aspnet-types.php Default.aspx→Default.aspx.vbの順番で処理させるとのことで記述がありました。 そのため、簡単ではないのかと想像してしました。 文章説明がうまくできずに申し訳ありません。 また、ASP.netは不慣れで経験が少ないため、パネルのこと誤解していることもあるかもしれません。 よき方法が見つかるようお付き合いいただければ幸いです。
退会済みユーザー

退会済みユーザー

2020/09/07 07:17 編集

レスが前後してしまいましたが、とりあえす回答しておきましたので、それに対するフィードバックを回答欄のコメントに書いてください。求めていることと違う場合は、どこがどう違うかなるべく具体的に書いてもらえると、修正案が出せるかもしれません。
coco0303

2020/09/07 07:26

ありがとうございます。 お時間割いていただきご回答もありがとうございます。 組み込んで動かしてみます。 明日になるかもしれませんがご連絡させてください。
guest

回答1

0

ベストアンサー

ユーザーパネルは50-200になると思います。

使用予定のユーザーコントロールが 50 - 200 ぐらいで非常に多いので Panel を切り替えるという案は NG で、どうしてもクエリ文字列によってロードするユーザーコントロールを切り替えるようにしたいと理解して・・・

以下のようにしてはいかがですか? Page.LoadControl メソッドを使って、ユーザーコントロールを読んでコンパイルして Control オブジェクトを生成し、PlaceHolder に追加するという方法です。

WebUserControl1.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.WebUserControl1" %> <h3>WebUserCintrol1</h3> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:Button ID="Button1" runat="server" Text="Button" />

WebUserControl2.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl2.ascx.cs" Inherits="WebApplication1.WebUserControl2" %> <h3>WebUserCintrol2</h3> <asp:DropDownList ID="DropDownList1" runat="server"> <asp:ListItem Value="1" Text="Orange"></asp:ListItem> <asp:ListItem Value="2" Text="Apple"></asp:ListItem> </asp:DropDownList> <br /> <asp:Button ID="Button1" runat="server" Text="Button" />

Default.aspx.cs

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication1 { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string s1 = Request.QueryString["s1"]; if (!string.IsNullOrEmpty(s1)) { if (s1 == "1") { Control ctrl = LoadControl("WebUserControl1.ascx"); PlaceHolder1.Controls.Add(ctrl); } else if (s1 == "2") { Control ctrl = LoadControl("WebUserControl2.ascx"); PlaceHolder1.Controls.Add(ctrl); } } } } }

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <h1>Page.LoadControl</h1> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </form> </body> </html>

クエリ文字列を s1=2 として(WebUserControl2.ascx を指定)実行した結果

イメージ説明

【追記】コードの Default.aspx と上の画像の WebForm10.aspx の名前が一致しませんが、同じものだと思ってください。

投稿2020/09/07 07:14

編集2020/09/07 07:28
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco0303

2020/09/08 00:02

SurferOnWwwさま おはようございます!昨日はソースのご教示ありがとうございます。 値の受け渡しなども問題なく無事に目的を達成することができそうです。 ありがとうございました。お力をお借りできたこと感謝申し上げます。
退会済みユーザー

退会済みユーザー

2020/09/08 00:07

今更ですが、ユーザーコントロールを Page に追加するタイミングは Page_Load より Page_Init の方が適切でした。理由は、ViewSate のロード、送信されてきたデータの反映、イベントの発生のタイミングの整合のためです。Page_Init でやってください。
coco0303

2020/09/08 02:07

ご親切に追記ありがとうございます。 変更してやってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問