【问题标题】:Highlight ListView row without re-bind or apply style to that row突出显示 ListView 行而不重新绑定或将样式应用于该行
【发布时间】:2021-11-20 21:45:06
【问题描述】:

典型的列表视图。

    <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" OnSelectedIndexChanging="ListView1_SelectedIndexChanging" 
        OnSelectedIndexChanged="ListView1_SelectedIndexChanged">
        <ItemTemplate>
            <tr style="">
                <td>
                    <asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' />
                </td>
                <td>
                    <asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' />
                </td>
                <td>
                    <asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' />
                </td>
                <td>
                    <asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' />
                </td>
                <td>
                    <asp:Button ID="cmdLstSel" runat="server" Text="View" CssClass="btn" 
                        CommandName="Select"/>
                </td>
            </tr>
        </ItemTemplate>
        <SelectedItemTemplate>
            <tr style="" class="alert-info">
                <td>
                    <asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' />
                </td>
                <td>
                    <asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' />
                </td>
                <td>
                    <asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' />
                </td>
                <td>
                    <asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' />
                </td>
                <td>
                    <asp:Button ID="cmdLstSel" runat="server" Text="View" CssClass="btn" OnClick="cmdLstSel_Click" />
                </td>
            </tr>

        </SelectedItemTemplate>
        <LayoutTemplate>
            <table runat="server">
                <tr runat="server">
                    <td runat="server">
                        <table id="itemPlaceholderContainer" runat="server" border="0" style="">
                            <tr runat="server" style="">
                                <th runat="server">FirstName</th>
                                <th runat="server">LastName</th>
                                <th runat="server">HotelName</th>
                                <th runat="server">City</th>
                                <th runat="server">View</th>
                            </tr>
                            <tr id="itemPlaceholder" runat="server">
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr runat="server">
                    <td runat="server" style="">
                        <asp:DataPager ID="DataPager1" runat="server">
                            <Fields>
                                <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" />
                            </Fields>
                        </asp:DataPager>
                    </td>
                </tr>
            </table>
        </LayoutTemplate>
    </asp:ListView>

所以我们可以突出显示点击的行:

   protected void ListView1_SelectedIndexChanging(object sender, ListViewSelectEventArgs e)
    {
        
    }

    protected void ListView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        GPayments.DataSource = MyRst("SELECT * FROM HotelPayments WHERE Hotel_ID = " + hID);
        GPayments.DataBind();
    }

现在如果我省略重新绑定,那么该行当然会突出显示,但当然是“上一个”行会突出显示。

如果我可以设置 ONE 行的类,那么我可以转储所选项目模板。

您可以在 GridView 中轻松做到这一点,我经常这样做:

    Dim gRow As GridViewRow = -- get any row

    gRow.CssClass = " alert-info"

但是,我想对 listView 做同样的事情。当我为 GridView 执行上述操作时,我不需要或不必费心重新绑定,我什至也不需要选定的模板。

所以左边是一个网格视图,我们得到这个:

但是,我想用 listview 来做到这一点。 (并且无需重新绑定)。

有什么简单的方法可以在不重新绑定的情况下突出显示 ListView 中的一行?

【问题讨论】:

    标签: c# asp.net vb.net listview webforms


    【解决方案1】:

    好的,用谷歌搜索一下,解决方案变得非常简单。

    这里的目标是点击一行 - 突出显示该行。

    当然,要包含选定的行模板需要做太多工作。

    为此添加 3 行代码是一个更好的折衷方案。

    所以,假设我们有这个标记:

        <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" 
            OnSelectedIndexChanged="ListView1_SelectedIndexChanged" OnSelectedIndexChanging="ListView1_SelectedIndexChanging" >
            <ItemTemplate>
                <tr id="mytr" runat="server">
                    <td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
                    <td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
                    <td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
                    <td><asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' /></td>
                    <td>
                        <asp:Button ID="cmdLstSel" runat="server" Text="View" CssClass="btn" 
                            CommandName="Select" OnClick="cmdLstSel_Click"/>
                    </td>
                </tr>
            </ItemTemplate>
            <LayoutTemplate>
                    <table id="itemPlaceholderContainer" runat="server" border="0" class="table table-hover" style="">
                        <tr runat="server" style="">
                            <th runat="server">FirstName</th>
                            <th runat="server">LastName</th>
                            <th runat="server">HotelName</th>
                            <th runat="server">City</th>
                            <th runat="server">View</th>
                        </tr>
                        <tr id="itemPlaceholder" runat="server">
                        </tr>
                    </table>
            </LayoutTemplate>
        </asp:ListView>
    

    好的,我们要填写的代码是这样的:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
                LoadView();
        }
    }
    void LoadView()
        {
            ListView1.DataSource = MyRst("SELECT TOP 12 * FROM tblHotels ORDER BY HotelName");
            ListView1.DataBind();
        }
    

    输出:

    好的,那么对于行点击?好吧,我们不必使用已更改的选定索引,但是,为此我们将(因此 CommandName="Select" 是触发索引更改事件的原因)。

    但是,我想要一个简单的按钮点击,并带有一些代码(显示详细信息部分)。

    所以,我们的按钮点击是这样的:

    protected void cmdLstSel_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
    
            int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
            GHotelOptions.DataSource = MyRst("SELECT * FROM HotelOptions WHERE Hotel_ID = " + hID);
            GHotelOptions.DataBind();
    
            GPayments.DataSource = MyRst("SELECT * FROM HotelPayments WHERE Hotel_ID = " + hID);
            GPayments.DataBind();
    
        }
    

    上面将填充子表。请注意获取行的酷技巧 - 我不关心 listview 事件模型!

    现在是行高亮显示。

    诀窍是像这样在 tr 行中添加一个“id”:

     <ItemTemplate>
          <tr id="mytr" runat="server">
    

    所以,我们现在可以拿起 tr 元素。

    所以在 lv 索引发生变化时,我们这样做:

        protected void ListView1_SelectedIndexChanged(object sender, EventArgs e)
        {
    
            ListViewItem gRow = (ListViewItem)ListView1.Items[ListView1.SelectedIndex];
            if ( (ViewState["MySel"] != null) && ((int)ViewState["MySel"] != gRow.DataItemIndex) )
            {
                ListViewItem gLast = ListView1.Items[(int)ViewState["MySel"]];
                HtmlTableRow hTRL = (HtmlTableRow)gLast.FindControl("mytr");
                hTRL.Attributes.Add("class", "");
            }
            HtmlTableRow hTR = (HtmlTableRow)gRow.FindControl("mytr");
            hTR.Attributes.Add("class", "alert-info");
    
            ViewState["MySel"] = gRow.DataItemIndex;
       }
    

    所以,我确实使用了行状态,但这让我可以取消突出显示 + 突出显示,而且我不必重新绑定网格。

    我刚刚选择了一个不错的引导类 - 它甚至可以“反转”文本 - 非常好。

    所以现在我们得到了这个:

    所以这确实花费了大约 4-5 行。但是,我们将其换成在 lv 中没有选定的模板(这对于维护行布局来说太过分了,然后必须为选定的模板维护相同的布局。更糟糕的是,您仍然必须为突出显示的行重新绑定点击显示。这样我们就不用了。

    我还使用“帮助”例程来获取数据表,就是这样:

    public DataTable MyRst(string strSQL)
    {
        DataTable rstData =  new DataTable();
        using (SqlCommand cmdSQL = new SqlCommand(strSQL,
            new SqlConnection(Properties.Settings.Default.TEST3)))
        {
            cmdSQL.Connection.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
        return rstData;
    }
    

    在一天结束时,我们现在可以突出显示该行,只需单击即可,我们甚至可以将选定的索引更改代码移动到我们的按钮代码,甚至不使用 lv 索引和内置事件。

    【讨论】:

      猜你喜欢
      • 2011-10-03
      • 2020-11-04
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多