0

ページ内の複数のレベルにネストされた asp.net コントロールに、カスタム バリデータからアクセスするにはどうすればよいですか?

具体的には、別のプレースホルダーの内側にある別のリピーターの内側にあるリピーターの内側にあるプレースホルダーの内側にあるドロップダウンリストを生成しています。

互いに比較するために、すべてのドロップダウン ボックスの選択された値にアクセスする必要があります。

私の現在の解決策は、ドロップダウンリストにアクセスするのに十分深くなるまで、各コントロール内のすべてのコントロールをループすることです:

    For Each g As Control In sender.Parent.Controls
        If g.GetType().ToString.Equals("System.Web.UI.WebControls.Repeater") Then
            For Each k As Control In g.Controls
                If k.GetType().ToString.Equals("System.Web.UI.WebControls.RepeaterItem") Then
                    For Each l As Control In k.Controls
                        If l.GetType().ToString.Equals("System.Web.UI.WebControls.Repeater") Then
                            For Each p As Control In l.Controls
                                If p.GetType().ToString.Equals("System.Web.UI.WebControls.RepeaterItem") Then
                                    For Each n As Control In p.Controls
                                        If n.GetType().ToString.Equals("System.Web.UI.WebControls.PlaceHolder") Then
                                            For Each c As Control In n.Controls
                                                If c.GetType().ToString.Equals("System.Web.UI.WebControls.DropDownList") Then

                                                'Add the dropdownlist to an array so that I can use it after all drop down lists have been added for validation.

これはリソースの無駄遣いのように思えます。カスタム バリデータからこれらのコントロールにアクセスするより良い方法はありますか?

4

2 に答える 2

0

$コンテナ名を連結してネストされたコントロールにアクセスできると思います。このようなもの:

ControlToValidate="panel1$usercontrol1$otherusercontrol$textbox1"

これにより、バリデーターによって実行される内部FindControl()呼び出しが発生しますが、これは多少コストがかかるため、このアプローチは慎重に使用する必要があります。

一般に、他のコンテナー内の深くネストされたコントロールにアクセスすることはあまり良い考えではありません。これらのコントロールは、ページ/コントロールのプライベート メンバーとして扱い、この方法でアクセスしないでください。本当に、本当にしなければならない場合にのみ、上記のアプローチを使用してください。

編集:これは完璧な解決策ではないかもしれませんが、私はこのようにします。ページを取得し、作成した新しいカスタム インターフェイスがページに実装されているかどうかを確認する新しい DropDownListX コントロール (DropDownList から派生) を作成します。このインターフェイスを使用してコントロールをページに登録すると、バリデーターがこのリストを調べて、登録された各コントロールを検証できます。何かのようなもの:

interface IValidationProvider
{
    void RegisterForValidation ( Control oCtrl );
}

ページにこのインターフェースを実装する必要があります。次に、新しい DropDownListX コントロールで:

protected override void OnLoad ( EventArgs e )
{
    IValidationProvider oPage = Page as IValidationProvider;

    if ( oPage != null )
        oPage.RegisterForValidation ( this );
}

次に、ページで検証が行われると、検証リスト内のコントロールのリストを調べて、1 つずつ検証できます。カスタム バリデーターには単一のコントロール名はありませんが、ControlToValidateネストされたリピーター内の複数のコントロールを検証する 1 つのバリデーターがあるため、適切と思われます。

このソリューションにより、現在の深いループを完全にスキップすることができます。検証が必要なコントロールがある場合は、それ自体が登録されます。それ以外の場合、ページのリストは空になり、チェックする必要はありません。これにより、コントロールを検索する必要がないため、コントロール名の文字列比較も回避されます。必要なときに自分自身を登録します。

于 2012-11-27T03:23:56.100 に答える
0

コントロールを再帰的に取得しようとしましたか?

private Control FindControlRecursive(Control root, string id) 
{ 
    if (root.ID == id)
    { 
        return root; 
    } 

    foreach (Control c in root.Controls) 
    { 
        Control t = FindControlRecursive(c, id); 
        if (t != null) 
        { 
            return t; 
        } 
    } 

    return null; 
} 
于 2012-11-27T03:42:58.713 に答える