2010-08-11 4 views
21

дает мне ошибку: методы привязки данных, такие как Eval(), XPath() и Bind() могут использоваться только в контексте управления базой данных.eval in if statement?

Я мог бы написать: <% # Eval ("SaveDate")! = DBNull.Value? do magic Но мне нужно сделать много магии html в if.

Я знаю, что я должен добавить #, чтобы использовать Eval, но не уверен в правильном синтаксисе.

ответ

30

One решение состоит в том, чтобы обернуть содержимое в теге runat = "server" с видимым значением, например

<div runat="server" Visible='<%# Eval("SaveDate") != DBNull.Value %>'> 
    do magic 
</div> 

div может быть любым HTML-тегом, но <asp:Panel> и <asp:PlaceHolder> также могут быть использованы. Обратите внимание, что «делать магия» по-прежнему является привязкой к базе данных, поэтому это не идеальное решение, если оно содержит дорогой код или код, который мог бы генерировать ошибку, если Eval("SaveDate") == DBNull.Value.

Обратите внимание, что Visible="false" опускают тег и все его содержимое из сгенерированного HTML, это означает, что он сильно отличается от style="display:none" или style="visible:hidden", так что не беспокойтесь об этом.

Но, если ваш «делать волшебство» является достаточно сложным, еще довольно простым решением (немного хака) является: использовать повторитель (или FormView) с DataSource, установленной в массив одного элемента (видимые) или какие-либо предметов (скрытые):

<asp:Repeater runat="server" DataSource='<%# ElementIfTrue(Eval("SaveDate") != DBNull.Value) %>' 
    <ItemTemplate> 
     do magic 
    </ItemTemplate> 
</asp:Repeater> 

protected IEnumerable ElementIfTrue(bool condition) 
{ 
    if (condition) 
     return new object[] { Page.GetDataItem() }; 
    else 
     return new object[0]; 
} 

фактическое содержание массива источника данных либо пусто (скрытый) или элемент, который вы уже связывались с. Это гарантирует, что вы все равно можете позвонить <%# Eval(...) %> внутри ItemTemplate.

С помощью этого подхода ваша магия «делать магия» является шаблоном, который будет выполняться только в том случае, если у DataSource есть один или несколько элементов. О чем заботится ElementIfTrue. Это немного изгиб ума, но он может сэкономить вам время от времени.

В качестве примечания стороны: упаковка вашей «магии» в пользовательском элементе управления также может снизить сложность. Вам не нужно ничего менять в своем теге HTML/ASP.NET (<%# Eval("...") %> все еще работает даже внутри пользовательского элемента управления).

+0

Я использую этот код в ретрансляторе, поэтому не могу использовать заполнители или любые ID из кода позади. –

+0

FYI: Я не могу использовать отображение: нет, поскольку текст индексов Google, который скрыт на дисплее, не блокируется. Я не могу использовать Visible = false, поскольку это ретранслятор, и я не могу использовать идентификаторы. Я мог бы скрыть это только с помощью инструкции if. –

+0

Вы можете привязать данные к Visible, это свойство на каждом сервере. Просто попробуйте '

won't be there!
' внутри вашего ретранслятора; вы обнаружите, что весь div ушел из HTML, когда вы вызываете свою страницу и просматриваете источник. – Ruben

8

Я обычно добавить защищенную функцию возвращает строку с фоновым кодом для создания контента:

На странице:

<%# Eval("SaveDate") != DBNull.Value ? GenerateContent() : string.Empty %> 

В моем классе:

protected string GenerateContent() 
{ 
    return "Hello, World!" 
} 
+1

Что делать, если я хочу вернуть много магии :), как html-блоки и т. Д. Должен ли я использовать метод от codebehind для этого? –