2011-07-13 15 views
2

例1:ここasp.net:子コントロールのVisibleプロパティはいつ自動的に設定されますか?

<asp:Panel Visible="false" runat="server"> 
    <asp:TextBox ID="textbox" runat="server" /> 
</asp:Panel> 

textbox.Visibleリターン(TextBox.Visibleが明示的に設定されていなかったにもかかわらず、その目に見えない親からプロパティを「継承」するように見える)のコードでfalse

例2:ここ

<asp:DataGrid ID="grid" runat="server" AutoGenerateColumns="false"> 
    <Columns> 
     <asp:TemplateColumn Visible="False"> 
      <ItemTemplate> 
       <asp:TextBox ID="textbox" runat="server" /> 
      </ItemTemplate> 
     </asp:TemplateColumn> 
    </Columns> 
    ... 
</asp:DataGrid> 

((TextBox)grid.Items[0].FindControl("textbox")).Visible戻りtrue(データグリッドは、少なくとも一つの列を有しているという仮定の下で)。


質問:がデザインすることで、この矛盾した行動ですか?いずれの場合も、親要素の一部が見えないため、TextBoxはレンダリングされません。

(テキストボックスは、テンプレート内にある第二の場合には、確かに、私はテンプレート定義の抽象テキストボックスを照会しないよ、私は、行番号0の特定の具体的なテキストボックスを照会しています)

背景: TextBoxはスマートコントロールです。TextBoxが表示されている場合、HTML <input>コントロールとしてレンダリングされ、現在のText値がポストバックに送信されます。ViewState経由で再度送信する必要はありません。もちろん、TextBoxが表示されていない場合はレンダリングされず、したがってTextプロパティの変更は失われます。

ここで、例2は私たちにいくつかの問題を与えています。 textboxはレンダリングされていると思っています(ILスパイによれば、のプロパティをチェックしているため、ViewStateは使用されず、コードで行われたtextbox.Textの変更はすべて失われます)。私は今これがバグかどうか疑問に思っています。


関連質問:How to get the set/real value of the Visible property in Asp.Net.


編集:私はこの上のマイクロソフト接続バグレポートを作成しました

答えて

4

TextBoxおよびPanelは、いずれもControlを継承するWebControlから継承する。 ControlVisibleプロパティに次の定義が含まれます。

public virtual bool Visible 
{ 
    get 
    { 
     return !this.flags[16] && 
       (this._parent == null || this.DesignMode || this._parent.Visible); 
    } 
    set 
    { 
     if (this.flags[2]) 
     { 
      bool flag = !this.flags[16]; 
      if (flag != value) 
      { 
       this.flags.Set(32); 
      } 
     } 
     if (!value) 
     { 
      this.flags.Set(16); 
      return; 
     } 
     this.flags.Clear(16); 
    } 
} 

VisibleTextBoxに直接実装されていませんので、指定した親がある場合、それは常に親のVisibleプロパティがfalseの場合、実行時に(falseを返します)。だから、タイトルで尋ねられた質問に答えるために、Visibleプロパティはいつでも自動的にfalseに設定されません。アクセスされたときに評価されます。 GridViewの場合、TextBox.Visibletrueを返した場合、TextBoxの親コントロールがTemplateColumnでないか、少なくとも親のVisibleプロパティがfalseに設定されていないことが原因です。

EDIT
ですから、アップコントロールのチェーンを歩けば、質問にあなたの例グリッドを使用して、あなたはTextBoxの親コントロールのすべてがVisibleていることがわかります。私は以下のコードを使用し、ここでの出力です:

TextBox (ClientID = grid_textbox_0, Visible = True) 
TableCell (ClientID = grid_ctl00_0, Visible = True) 
DataGridItem (ClientID = grid, Visible = True) 
ChildTable (ClientID = grid_ctl00, Visible = True) 
DataGrid (ClientID = grid, Visible = True) 
HtmlForm (ClientID = form1, Visible = True) 

コード:

protected void btnSubmit_Click(object sender, EventArgs e) 
{ 
    var control = grid.Items[0].FindControl("textbox"); 
    while(control != this && control != null) 
    { 
     Response.Write(string.Format("{0} (ClientID = {1}, Visible = {2})", 
      control.GetType().Name, control.ClientID, control.Visible)); 
     Response.Write("<br />"); 
     control = control.Parent; 
    } 
} 

予想通りDataGridVisisble性質が働いているように私には思えます。

+0

+1、説明のためにありがとうございます。私は答えとして受け入れる前にちょっと待っています。なぜ、これが例2で正しく動作しないのか不思議であるからです。結局、再帰的に表示するコードは '_parent.Visible'を呼び出します。直接の親だけでなく、親ツリーの上に隠されたコントロールがあります。 – Heinzi

+0

@ Heinzi今日の後半の例2を詳しく見てみよう。たぶん、GridViewはそれ自身のVisible実装か何かを持っています。 – rsbarro

+0

@Heinzi 2番目の例でTextBoxがVisibleとして表示されている理由を示すために、私の答えを更新しました。しかし、私が混乱していることの1つは、TemplateColumnが表示されていない場合、TextBoxの値がどのように変化するのでしょうか?グリッドがデータバインドされているときにTextBoxを値に設定していて、それをPostBackに戻すことができないと言っていますか? – rsbarro

関連する問題