Как я могу воспроизвести, если ... Тогда логика в качестве веб-элемента управления? - PullRequest
2 голосов
/ 18 августа 2010

У меня есть дизайнер, работающий на уровне ASPX. Он не работает на C #, не выполняет программный код, не компилирует и т. Д. Он чистый дизайнер, работает с HTML и серверными элементами управления.

Мне нужен условный контроль - вещь типа 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>

Ответы [ 3 ]

2 голосов
/ 26 августа 2010

Вместо записи управления

asp:If

почему бы не использовать:

<% if expression
       { %>
    Yellow
    <% } %>
    <% else
        {%>
    Red
    <% } %>
2 голосов
/ 19 ноября 2012

Принимая во внимание, что файлы с зашифрованными кодами отсутствуют, так как дизайнер, вероятно, не получил 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> можно изменить на другоетип веб-элемента управления, например <asp:label> и т. д. Я думаю, что почти все элементы управления dot net имеют свойство visible, поэтому их можно скрыть / показать в любое время.

0 голосов
/ 26 августа 2010

Синтаксис привязки данных имеет две проблемы: во-первых, это немного странно для вашего дизайнера по сравнению с использованием простого текста, а во-вторых, он требует от разработчика помнить об инвертировании теста «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, или другие способы динамической компиляции кода, хотя производительность будет проблемой, так как вы, вероятно, в конечном итоге будете динамически компилировать код при каждом запуске страницы, это может вызвать неприятные проблемы с безопасностью и многое другое.Я бы держался подальше от этого.

...