1

クライアントで操作できるカスタムASP.Netサーバーコントロールを開発しようとしています。ポストバック後に変更を保存するために、非表示のフィールドがあります。OnLoadイベントで、プロパティを書き込むための値を取得しましたが、コントロールが既に作成されているため、遅すぎるようです。PreRenderイベントのコントロールを操作できることは知っていますが、これを処理するためのより良い方法があるように思われます。誰かアイデア?

public class Control : CompositeControl {

  private bool mProperty;
  private HiddenField hiddenField;


  public virtual bool Property {
    get {
      return mProperty;
    }
    set {
      mProperty = value;
    }
  }
  protected override void CreateChildControls() {
    Controls.Clear();
    CreateControlHierarchy();
    ClearChildViewState();
  }
  protected virtual void CreateControlHierarchy() {
    CreateHiddenField();
    CreateContent();
  }

  protected virtual void CreateHiddenField() {
    hiddenField = new HiddenField();
    hiddenField.ID = "hiddenField";
    hiddenField.Value = Property.ToString().ToLower();
    Controls.Add(hiddenField);
  }  
  protected virtual void CreateContent() {
    contentPanel = new Panel();
    contentPanel.ID = "content";
    contentPanel.Vsiible = Property;
    Controls.Add(contentPanel);
  }
  protected override void OnLoad(EventArgs e) {
    base.OnLoad(e);
    if(Page.IsPostback) {
      Property = Convert.ToBoolean(Page.Request.Form[hiddenField.UniqueId]);
    }
  }
}

考えられる解決策の編集:

OnLoadイベントを取り除き、次のようにプロパティを編集しました。

public virtual bool Property { 
  get { 
    if (Page.IsPostBack) {
      EnsureChildControls();
      return Convert.ToBoolean(Page.Request.Form[hiddenField.UniqueID]);
    }
    return mProperty; 
  }
  set { 
    mProperty = value;
  }
}

それは良いアプローチですか?

4

2 に答える 2

1

プロパティはコントロールの作成時にのみ使用されるため、1つの提案はプロパティとコントロールの両方にポストバック値を設定することです。

 protected override void OnLoad(EventArgs e) {
    base.OnLoad(e);
    if(Page.IsPostback) {
      if(hiddenField != null)
         hiddenField.Value = Page.Request.Form[hiddenField.UniqueId].ToString();

      Property = Convert.ToBoolean(Page.Request.Form[hiddenField.UniqueId].ToString());    
    }
  }
于 2013-03-25T11:16:35.003 に答える
1

隠しフィールドにValueChangedEventHandlerを実装し、プロパティのセッターを編集してすべての依存関係を処理することで、やりたいことを達成しました。

public class Control : CompositeControl {

  private bool mProperty;
  private HiddenField hiddenField;


  public virtual bool Property {
    get {
      return mProperty;
    }
    set {
      mProperty = value;
      if (contentPanel != null) contentPanel.Visible = value;
      if (hiddenField != null && hiddenField.Value != value.ToString().ToLower()) hiddenField.Value = value.ToString().ToLower();
    }
  }
  protected override void CreateChildControls() {
    Controls.Clear();
    CreateControlHierarchy();
    ClearChildViewState();
  }
  protected virtual void CreateControlHierarchy() {
    CreateHiddenField();
    CreateContent();
  }

  protected virtual void CreateHiddenField() {
    hiddenField = new HiddenField();
    hiddenField.ID = "hiddenField";
    hiddenField.Value = Property.ToString().ToLower();
    hiddenField.ValueChanged += hiddenField_ValueChanged;
    Controls.Add(hiddenField);
  }  
  protected virtual void CreateContent() {
    contentPanel = new Panel();
    contentPanel.ID = "content";
    contentPanel.Vsiible = Property;
    Controls.Add(contentPanel);
  }
  void hiddenField_ValueChanged(object sender, EventArgs e) {
    Property = Convert.ToBoolean(hiddenField.Value);
  }
  protected override void OnInit(EventArgs e) {
    EnsureChildControls();
    base.OnInit(e);
  }
}
于 2013-03-25T12:20:34.030 に答える