2009-10-29 37 views
5

オブジェクトに関する情報を表示するために複数のページで使用するユーザーコントロールがあります。このusercontrolを使用する必要があるときは、Display(usercontrol上)というメソッドを呼び出し、いくつかの値を渡します。foreachループ内のユーザーコントロールのプロパティを設定する

public void Display(string name, List<Items> items) 
{ 
    // Set a few protected properties so I can display values from the aspx page 
} 

これはうまくいきましたが、今はこのコントロールをaspxページのforeachループ内で使用する必要があります。

<% foreach (var c in Categories) { %> 
     <uc:ItemsControl runat="server"/> 
<% } %> 

categoriesオブジェクトには、それ以外の方法でDisplayメソッドに渡すメソッドとプロパティがあります。では、どうすれば値を適切に設定できますか?

私は、ユーザーコントロールのパブリックのプロパティを作り、ちょうどこの方法でそれらを設定してみました:

<uc:ItemsControl Items="<%# c.Items %>" 
       OtherProperty="<%# c.GetProperty() %>" 
       runat="server"/> 

これは動作しません、で送信されたばかりのプロパティが空であるため。 <%=を使用しても動作しませんし、実際には 'c'を認識しないためエラーが発生します(runat = "server"を取り除かないと、少なくともコンパイルされますが、 。これを行うための適切な方法は何ですか

編集:?。また、Repeaterコントロールがデータバインディングのためにこれを簡単に作るかもしれないが、私は任意の.NETコントロールの使用を避けることを好むだろう

答えて

0

Justin Grant's answerはそううまく働いたHAVだろうが、私たちはユーザーコントロールをロードし、DisplayResultsメソッドを呼び出すことで行くことにしました。

<% ((UserControlType)LoadControl("~/pathToUserControl.ascx")) 
     .DisplayResults(ItemName, ItemList)); %> 

これは完全なコードではありませんが、私が質問で取り上げた問題を解決するために必要だったものです。この方法でユーザーコントロールを読み込むことで、必要なプロパティを設定し、uesrコントロールを正しい情報で表示できます。

10

WebFormsページでは、これはDataBindingを使用して通常処理する方法です。foreachループの代わりにRepeaterコントロールを使用し、DataSourceプロパティを<%#Categories%>に設定してから、ラテックスでデータバインディング構文を使用します上の例では、cの代わりに、Container.DataItemをコントロールの適切な型にキャストする必要があります。このように:

<%@ Page Language="C#" %> 
<script runat="server"> 
protected void Page_Load(object sender, EventArgs e) 
{ 
    CategoriesList.DataBind(); 
} 
class Category 
{ 
    public string CategoryName { get; set; } 
    public string GetProperty() { return CategoryName; } 
    public string[] Items { get { return new string[] {CategoryName + " 1", CategoryName + " 2"}; } } 
} 
Category[] Categories = new Category[] 
{ 
    new Category { CategoryName = "Shorts" }, 
    new Category { CategoryName = "Socks" }, 
    new Category { CategoryName = "Shirts" }, 
}; 
</script> 
<html> 
<body> 
<asp:Repeater runat="server" ID="CategoriesList" DataSource="<%# Categories %>"> 
    <ItemTemplate> 
    <uc:ItemsControl 
     Items="<%# ((Category)(Container.DataItem)).Items %>" 
     OtherProperty="<%# ((Category)(Container.DataItem)).GetProperty() %>" 
     runat="server"/> 
    </ItemTemplate>  
</asp:Repeater> 
</body> 
</html> 

唯一の注意点は、あなたが一般的にPage_Load方法では、somwhereリピータのDataBindを()メソッドを呼び出す必要がありますです。

個人的には、データバインディングがキャストとデータバインドを呼び出す必要性の両方が、私が上で試したforeachメソッドよりもはるかに自然ではないように感じています。これはおそらく、私がASP.NET MVCについて最も気に入っていることです。MVC Viewsは、はるかに簡単なIMHOのforeachモデルをはるかに簡単に使用できます。つまり、WebFormsに固執しなければならないのであれば、キャスティングとのデータ結合は最も抵抗の少ないパスです。それは、プレーンテキスト出力のため のみ有用ではありませんsyntax--にrunat =サーバーのASP.NETコントロールのプロパティが <%= %>を用いて充填することはできません

  1. :ので

    ところで、上記のあなたのアプローチは動作しませんでしたオブジェクトプロパティを埋め込むために )(データバインディング構文(<%# %>)を使用して

  2. は間違いなくコントロールのプロパティで を埋めるために使用することができますが、(リピータのような)データバインディング コンテナ内のコントロールをラップし、 のDataBindを呼び出すために が必要 の置換が行われるようにします。

+1

リピータはおそらく適切な方法ですが、可能な限り.NETコントロールの使用を避けようとしており、HTMLを生成することをお勧めします。 – Brandon

+0

まあ、私も - 私はループとエミットのHTMLのアプローチをはるかに簡単に見つける。だから私はASP.NET MVCが好きです。しかし、Webフォームでは、独自のカスタムコントロールを使用しており、特にループ内でそのプロパティを設定する必要がある場合は、データバインディングを使用するのが最も簡単な方法です。好奇心のために、asp.netの組み込みコントロールを避けるのはなぜですか?これはパフォーマンスに関連する問題なのでしょうか?リピータのコントロールは非常に素早く素早く、そのようなビューステートや他のクルードを引き起こさない。リピータは、コントロールとして偽装するforeachループのように動作することができます。 –

+0

これは、一貫性/パフォーマンス上の懸念が増しています。コントロール/ AjaxToolKitは必要なだけ重すぎて純粋なHTML/jQueryのアプローチがとられたので、私の上司は当初はプロジェクトの.NETコントロールを持たずにいました。他のすべてが失敗した場合、私は1つのリピータを投入することができました。すでに開始したパスを使用してこれを行う方法があるかどうか疑問に思っていました。 – Brandon

1

私はこれが古いと知っていますが、このスレッドはかなり瞬時にGoogleで見つけられましたので、これを入力します。

foreachのUserControlsでこれを行うことができることを同僚の手伝いをするときに気がつきました。私は彼の例を通してそれをテストしたことに注意してください。

<% foreach (var c in Categories) { %> 
     <uc:ItemsControl runat="server" ID="ucItem"/> 
<% 
ucItem.PropertyToChange = c.Property; 
} %> 

これが少なくともあなたには当てはまらない場合は、他の人には当てはまるかもしれません。

+1

コントロールを呼び出す前にプロパティを設定する必要があります。それ以外の場合は、ループ内で使用されるコントロールの単一のインスタンスの単純なケースであれば便利です。 – Reuben

関連する問題