1

定型化されたフォーム要素をレンダリングするために使用している WebControl ライブラリがあります。ライブラリにはいくつかのオーバーライドされたバリデータも含まれているため、一緒に使用すると、デフォルトのバリデータの red-star-next-to-a-field よりも優れた検証 HTML/CSS をレンダリングできます。つまり、行全体を強調したいと思います。

最も基本的なレベルでは、「フォーム ライン」は次のようにレンダリングできます。

  • アウター<div class="hasError">
    • <asp:Label>
    • <asp:TextBox>

(そこから、あらゆる種類の余分なホイッスル、AssociatedControlID...)

私が抱えている問題は、コントロールに独自のオーバーライドされたバリデーターを作成させる場合 (たとえば、IsRequiredFieldプロパティで制御する場合)、バリデーターのControlToValidateを取得してコントロール自体をターゲットにできないことです。

バリデーターのターゲット ControlToValidateは、コントロール ツリーの同じレベルにある必要があるようです。また、エラーが発生するため、CreateChildControls中に親のコントロール ツリーに追加することはできません 。

...だから私はこのようなクラスを持っています:

[DefaultProperty("Value"), ValidationProperty("Value")]  
public class BasicTextInputLine : WebControl, INamingContainer  
{  
  ...
  private Label _someLabel;
  private TextBox _someTextBox;
  private MyRequiredFieldValidator _someValidator;

  public string Value  
  public bool IsRequiredField  
  ...  
}  

(- ValidationProperty("Value") フラグにより​​、バリデーターはそれを指すことができます)

public class MyRequiredFieldValidator : RequiredFieldValidator
{
  ...
  protected override void OnPreRender(EventArgs e)
  {
    ...
    if (foundControlToValidate is BasicTextInputLine)
      (foundControlToValidate as BaseFormEntry).IsValid = false;
}

次のように、マークアップで喜んで作業できます。

<custom:BasicTextInputLine ID="foo" ... />
<custom:MyRequiredFieldValidator ControlToValidate="foo" ... />

問題:
残念ながら、コントロール ツリーに何かを追加するときに catch-22 が発生します。

それを親に追加すると (これにより、動作するコントロール ツリーが得られます)、そのコントロール セットに干渉できないというエラーが発生します。

protected override void CreateChildControls()
{
  ...
  Parent.Controls.Add(_someValidator);
}

コントロールに追加すると、ControlToValidateが見つからないというエラーが発生します。

protected override void CreateChildControls()
{
  ...
  Controls.Add(_someValidator);
}

これを構造化して、BasicTextInputLine に独自のバリデータを作成させ、内部の TextBox ではなく、それ自体を検証させるにはどうすればよいでしょうか?

とても有難い。

4

1 に答える 1

1

問題を完全に理解しているかどうかはわかりませんが、コード スニペットを解釈すると、ここで 2 つの概念が混在しています。

  1. BasicTextInputLine にはバリデーターが直接含まれています。特にクラスの変数によってその情報を導き出します。

    プライベート MyRequiredFieldValidator _someValidator;

    子コントロールのリストに追加しようとしています。

  2. バリデーターは、メインの BasicTextInputLine を参照する完全に分離されたコントロールです。あなたのマークアップでそれを見ることができます:

これら 2 つのアプローチは矛盾していると思います。2 つの選択肢があります。

  1. アプローチ 1 に固執します。その場合、コード内にバリデータ インスタンスを作成し、マークアップ部分を削除する必要があります。

  2. アプローチ 2 に固執します。その場合、BasicTextInputLine クラスはバリデータについて知る必要はありません。つまり、クラス内の変数を削除し、子コントロールとして作成しないでください。あなたは単にそれを必要としません。

于 2011-03-18T23:50:24.527 に答える