質問

Simple example: (.NET 3.5)

  1. a SQLDataSource returning COL_A and COL_B columns,

  2. a DataList control using the sqldatasource

  3. inside a "item template" I want to have different sections depending on values of A or B:

    <ItemTemplate>
    <span class="item_title"><%# Eval("COL_A")%></span><br/> 
    
    <% if ( GET_DATA("COL_B") > 100 )   
    {
    %>
        <span>SOMETHING HERE</span>
    
    <%  }
    else
    {
    %>
        <span>DIFFERENT MARKUP HERE</span>
        <span>SOMETHING COMPLETELY DIFFERENT HERE</span>
    <%
    }
    %>
    

The question is: What to use instead of GET_DATA to access value passed from SQL?

正しい解決策はありません

他のヒント

Conditional markup is not supported in ItemTemplate's. The best you can do here is to make your spans server-side and manipulate their Visible property:

<ItemTemplate>
    <span class="item_title"><%# Eval("COL_A")%></span><br/> 

    <span runat="server" Visible='<%# (int)Eval("COL_B") > 100 %>'>
        SOMETHING HERE
    </span>
    <span runat="server" Visible='<%# (int)Eval("COL_B") <= 100 %>'>
        DIFFERENT MARKUP HERE
    </span>
    ...

Or you can wrap them in placeholders if you want to - might be a bit cleaner solution.

Using scripting code like that probably isn't going to work. I don't think you can mix script in with templated controls: the script is interpreted at a different time from the databinding.

What you could do, though, is have a UserControl in your ItemTemplate that defines a property for ColB and displays different markup depending on COL_B's value.

<ItemTemplate>
     <span class="item_title"><%# Eval("COL_A")%></span><br/> 

     <uc1:UserControl1 runat="server" ColB='<%# (int)Eval("COL_B") %>' />
</ItemTemplate>

Then in your user control markup you have two or more Panel controls:

<asp:Panel id="panel1" runat="server">
   <span>SOMETHING HERE</span>
</asp:Panel>
<asp:Panel id="panel2" runat="server">
   <span>DIFFERENT MARKUP HERE</span>
   <span>SOMETHING COMPLETELY DIFFERENT HERE</span>
</asp:Panel>

... and then in your PreRender event in the user control code-behind (don't use Load, because your binding in the parent won't have happened yet):

 panel1.Visible = false;
 panel2.Visible = false;
 if(this.ColB > 100)
    panel1.Visible = true;
 else
    panel2.Visible = true;

You could promote those two Panel controls to your parent page, but then you'd have to do a .FindControl() call in the ItemDataBound event handler in order to change their properties, and extract COL_B's value from the e.Item.DataItem property. Lots of retrieving values and casting.

Thank you all for your input, it directed me towards the solution.

I, however, found a different solution that I will share here as it is neat and simple:

asp:PlaceHolder 

Element can be nested multiple times to generate very clean HTML output. Example below:

<asp:DataList ID="DataListLeft" runat="server" DataSourceID="SqlDataSource1" 
  RepeatLayout="Flow" RepeatDirection="Horizontal" >
    <ItemTemplate>                    
        <asp:PlaceHolder ID="PlaceHolder1" runat="server" 
          Visible='<%# !String.IsNullOrEmpty((string)Eval("COL_A", "{0}")) %>' >

            SOME HTML MARKUP HERE WHEN COL_A HAS A VALUE
            NOTE THE '!' IN CONDITION

        </asp:PlaceHolder>
        <asp:PlaceHolder ID="PlaceHolder2" runat="server" 
          Visible='<%# String.IsNullOrEmpty((string)Eval("COL_A", "{0}")) %>' >

            SOME HTML MARKUP HERE WHEN COL_A IS NULL OR EMPTY
            eg. <span>Data is not available</span>

        </asp:PlaceHolder>
    </ItemTemplate>
</asp:DataList>

Again, Thanks for your time.

JK

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top