2010-08-18 12 views
2

我有一位設計師在ASPX級別工作。他不做C#,不做代碼隱藏,不編譯等。他是一個純粹的設計師,使用HTML和服務器控件。如何將If ... Then邏輯複製爲Web控件?

我需要一個條件控制 - 一個If ... Then-ish類型的東西。通常情況下,我會這樣做:

<asp:Placeholder Visible='<%# DateTime.Now.Day == 1 %>' runat="server"> 
    It's the first day of the month! 
</asp:PlaceHolder> 

有沒有辦法做這樣的事情沒有數據綁定語法?類似於:

<asp:If test="DateTime.Now.Day == 1" runat="server"> 
    It's the first day of the month! 
</asp:If> 

是否有某種方式來擴展佔位符以允許此?我已經擺弄了一下,但最後,我有一個條件,我基本上必須編譯。

現在,數據綁定的語法沒有什麼問題,但只是一點......古怪,設計師必須明白。另外,它不會給我「其他」的陳述。這樣的事情將是巨大的......

<asp:If test="DateTime.Now.Day == 1" runat="server"> 
    It's the first day of the month! 
    <asp:Else> 
    It's not the first day of the month! 
    </asp:Else> 
</asp:If> 
+0

如果我有這個問題,我會把兩個面板控件,一個爲每個條件,我自己設置各自的可見屬性,並告訴我的程序員正確地編碼每一個。這自然會導致我在同一時間插入測試基礎架構。 – 2010-08-30 14:45:38

回答

0

數據綁定語法有兩個問題:第一個它是你的設計師有點怪異與使用純文本,其次它要求設計者要記得反轉「if」在你的「else」塊中測試。

第一個問題可能會讓您的設計師煩惱一點,但第二個問題更加嚴重,因爲它會迫使您的設計師像程序員一樣思考(反轉布爾邏輯!),並使每個if/else塊成爲可能的錯誤您需要在設計師交出模板後進行測試。

我的建議是:使用數據綁定語法,但通過創建僅需要If控件上的數據綁定測試代碼的自定義控件來修復更嚴重的問題,但不能控制Else控件。當然,你的設計師必須輸入更多的字符,但其他更嚴重的問題將不會適用,並且你的性能不會像每次頁面運行時必須動態編譯代碼一樣。

下面是我編寫了一個例子來說明:

<%@ Page Language="C#"%> 
<%@ Register Assembly="ElseTest" TagPrefix="ElseTest" Namespace="ElseTest"%> 

<script runat="server"> 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     DataBind(); 
    } 
</script> 

<html> 
<body> 

    <ElseTest:IfControl runat="server" visible="<%#1 == 1 %>"> 
     This should be visible (in "if" area) 
    </ElseTest:IfControl> 
    <ElseTest:ElseControl runat="server"> 
     This should not be visible (in "else" area) 
    </ElseTest:ElseControl> 

    <br /><br /> 

    <ElseTest:IfControl runat="server" visible="<%#0 == 1 %>"> 
     This should not be visible (in "if" area) 
    </ElseTest:IfControl> 
    <ElseTest:ElseControl runat="server"> 
     This should be visible (in "else" area) 
    </ElseTest:ElseControl> 

</body> 
</html> 

這裏的基本控件,這是簡單的包裝器asp:Literal

using System; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

[assembly: TagPrefix("ElseTest", "ElseTest")] 
namespace ElseTest 
{ 
    // simply renames a literal to allow blocks of data-bound-visibility 
    [ToolboxData("<{0}:IfControl runat=\"server\"></{0}:IfControl>")] 
    public class IfControl : Literal 
    { 
    } 

    [ToolboxData("<{0}:ElseControl runat=\"server\"></{0}:ElseControl>")] 
    public class ElseControl : Literal 
    { 
     public override bool Visible 
     { 
      get 
      { 
       // find previous control (which must be an IfControl). 
       // If it's visible, we're not (and vice versa) 
       for (int i = Parent.Controls.IndexOf(this)-1; i >= 0; i--) 
       { 
        Control c = Parent.Controls[i]; 
        if (c is IfControl) 
         return !c.Visible; // found it! render children if the if control is not visible 
        else if (c is Literal) 
        { 
         // literals with only whitespace are OK. everything else is an error between if and then 
         Literal l = c as Literal; 
         string s = l.Text.Trim(); 
         if (s.Length > 0) 
          throw new ArgumentException("ElseControl must be immediately after an IfControl"); 
        } 
       } 
       throw new ArgumentException("ElseControl must be immediately after an IfControl"); 
      } 
      set 
      { 
       throw new ArgumentException("Visible property of an ElseControl is read-only"); 
      } 
     } 
    } 
} 

如果你想讓它更簡潔,你可以很容易地縮短標籤名稱(通過更改類名稱和/或標籤前綴)。您也可以創建一個新屬性(例如「測試」)來代替「可見」。

如果你真的擺脫<%# %>,有likley很多不同的技巧,你可以用它來利用的CodeDOM或其​​他方式來動態編譯代碼,但性能將是一個挑戰,因爲你可能會結束每次頁面運行時動態編譯代碼,可能會引入討厭的安全問題等等。我會遠離那個。

+0

不是我一直在尋找的東西,但它是經過深思熟慮並朝着正確方向邁出的一步。 – Deane 2010-08-30 14:43:23

2

而是寫控制的

asp:If 

爲什麼不使用:

<% if expression 
     { %> 
    Yellow 
    <% } %> 
    <% else 
     {%> 
    Red 
    <% } %> 
+0

請注意,如果表達式依賴於Page_Load中生成的運行時數據,回發代碼等,因爲上面的表達式在運行服務器端事件處理程序之前的頁生命週期的早期進行了評估,所以這不起作用。 – 2010-08-27 06:27:54

2

考慮到該代碼隱藏文件已經爲設計者可能沒有得到VS,我想用更少的代碼更簡單的解決方案帳戶可能更優惠:

<%@ Page Language="C#"%> 

<script runat="server"> 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (DateTime.Now.Day == 1) 
     { 
      DateTestPanelFirst.visible = true; 
      DateTestPanelOther.visible = false; 
     } 
    } 
</script> 

<html> 
<body> 

<asp:panel runat="server" id="DateTestPanelFirst" visible="false"> 
    It's the first day of the month! 
<asp:panel> 

<asp:panel runat="server" id="DateTestPanelOther"> 
    It's not the first day of the month! 
<asp:panel> 

</body> 
</html> 

<asp:panel>可以更改爲ano其他網絡控制類型,如<asp:label>等。我認爲幾乎所有的網絡控制都具有可見性,因此您可以隨時隱藏/顯示它們。