2011-07-13 70 views
2

實施例1:asp.net:何時自動設置子控件的Visible屬性?

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

這裏,textbox.Visible返回false在代碼(即使TextBox.Visible沒有顯式地設置,它似乎是「繼承」從它的不可見的父屬性)。

實施例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是一個智能控件:It only saves its Text property in the ViewState if it's invisible.這是有道理的:如果文本框是可見的,它將呈現爲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

TextBoxPanel都從WebControl繼承,它繼承自ControlControl先後爲Visible屬性如下定義:

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); 
    } 
} 

由於Visible未在TextBox直接執行,它總是返回false如果父的Visible屬性爲false(在運行時,如果有指定的父)。因此,要回答標題中提出的問題,Visible屬性在任何時間點都不會自動設置爲false,只是在訪問時纔對其進行評估。在GridView的情況下,其中TextBox.Visible返回true,這意味着TextBox的父控件不是TemplateColumn,或者至少父母的Visible屬性沒有設置爲false。

編輯
因此,使用示例格中的問題,如果你走的控制鏈,你會發現一切爲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我更新了我的答案,以顯示TextBox在第二個示例中顯示爲可見的原因。有一件事我很困惑,但如果TemplateColumn不可見,TextBox的值如何改變?你是否在說,當網格是數據綁定時你將TextBox設置爲一個值,然後你不能在PostBack上讀取它? – rsbarro

相關問題