web-dev-qa-db-ja.com

ifステートメントで評価しますか?

 <% if(Eval("SaveDate") != DBNull.Value){ %>
     do magic                           
 <%} %>

エラーが発生します:Eval()、XPath()、Bind()などのデータバインディングメソッドは、データバインディングコントロールのコンテキストでのみ使用できます。

次のように書くことができます:<%#Eval( "SaveDate")!= DBNull.Value? do magicしかし、ifステートメントで多くのhtmlmagicを実行する必要があります。

Evalを使用するには#を追加する必要があることはわかっていますが、正しい構文についてはわかりません。

21
Stewie Griffin

1つの解決策は、コンテンツをrunat = "server"タグでVisible値でラップすることです。

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

divは任意のHTMLタグにすることができますが、_<asp:Panel>_および_<asp:PlaceHolder>_も使用できます。 「domagic」はまだデータバインドされているため、高価なコードやEval("SaveDate") == DBNull.Valueの場合にエラーを生成する可能性のあるコードが含まれている場合は完全なソリューションではないことに注意してください。

_Visible="false"_は、生成されたHTMLからタグとそのすべてのコンテンツを省略します。つまり、_style="display:none"_または_style="visible:hidden"_とは大きく異なるため、心配する必要はありません。

しかし、「魔法をかける」isかなり複雑な場合、別のかなり単純な解決策(ちょっとしたハック)は次のとおりです。データソースを1つのアイテムの配列に設定したRepeater(またはFormView)を使用します(表示)またはアイテムなし(非表示):

_<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];
}
_

データソース配列の実際の内容は、空(非表示)か、既にバインドしていた要素のいずれかです。これにより、ItemTemplate内で<%# Eval(...) %>を引き続き呼び出すことができます。

このアプローチでは、「do magic」は、DataSourceに1つ以上のアイテムがある場合にのみ実行されるテンプレートです。これはElementIfTrueによって処理されます。それは少しマインドベンダーですが、それは時々あなたを救うことができます。

補足として、ユーザーコントロールに「魔法をかける」ことを詰め込むことで、複雑さを抑えることもできます。 HTML/ASP.NETタグミックスの内容を実際に変更する必要はありません(<%# Eval("...") %>はユーザーコントロール内でも機能します)。

30
Ruben

私は通常、コンテンツを生成するためにコードビハインドに文字列を返す保護された関数を追加します。

ページ上:

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

私のクラスで:

protected string GenerateContent()
{
    return "Hello, World!"
}
8
kbrimington