2010-08-18 23 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>等。我认为几乎所有的网络控制都具有可见性,因此您可以随时隐藏/显示它们。