Синтаксис привязки данных имеет две проблемы: во-первых, это немного странно для вашего дизайнера по сравнению с использованием простого текста, а во-вторых, он требует от разработчика помнить об инвертировании теста «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");
}
}
}
}
Если вы хотите, чтобы это было более кратким, выможет легко сократить имя тега (путем изменения имен классов и / или префикса тега).Вы также можете создать новое свойство (например, «test»), которое будет использоваться вместо «Visible».
Если вы действительно хотите избавиться от <%# %>
, существует множество другихразличные приемы, которые вы можете использовать для использования CodeDOM, или другие способы динамической компиляции кода, хотя производительность будет проблемой, так как вы, вероятно, в конечном итоге будете динамически компилировать код при каждом запуске страницы, это может вызвать неприятные проблемы с безопасностью и многое другое.Я бы держался подальше от этого.