【问题标题】:Possible to remove tag item from Literal可以从文字中删除标签项目
【发布时间】:2016-10-19 09:45:45
【问题描述】:

我有以下代码

namespace WebApplication3
{
    public partial class WebForm2 : System.Web.UI.Page
    {
        class Customer
        {
            public Customer(int id, string fName)
            {
                ID = id;
                FirstName = fName;
            }

            public int ID { get; set; }
            public string FirstName { get; set; }
        }

        private List<Customer> GetCustomerNames()
        {
            // Add Customers to list - this is essentially coming from a database
            List<Customer> Names = new List<Customer>();
            Names.Add(new Customer(1, "Name 1"));
            Names.Add(new Customer(2, "Name 2"));
            Names.Add(new Customer(3, "Name 3"));
            Names.Add(new Customer(4, "Name 4"));

            return Names;
        }

        private void DropdownNames()
        {
            // Set the dropdown
            ddlName.DataSource = GetCustomerNames();
            ddlName.DataTextField = "FirstName";
            ddlName.DataValueField = "ID";
            ddlName.DataBind();
        }

        private void SetNameHTML(List<Customer> Names)
        {
            // The below code would set the literal control with the values coming from the list along with custom span so the design would be correct
            Int32 Count = 0;
            lit1.Text = string.Empty;

            foreach (Customer c in Names)
            {
                if (Count == 0)
                {
                    // IF first element then set active class so correct style is applied
                    lit1.Text += string.Format("<span class='square active' ID='spName' runat='server' data-value='{0}'>{1}</span> <br />", c.FirstName, c.ID);
                    spName.InnerText = c.FirstName;
                }
                else
                {
                    // Other non selected items - Note no active listed in the class
                    lit1.Text += string.Format("<span class='square' ID='spName' runat='server' data-value='{0}'>{1}</span> <br />", c.FirstName, c.ID);
                }

                Count += 1;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                DropdownNames();
                SetNameHTML(GetCustomerNames());
            }

        }

        protected void ddlName_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Get customer names again as the list would be empty if the SetNameHTML is removed
            var CustomerNames = GetCustomerNames();
            SetNameHTML(CustomerNames);
            // Get a single customer to set the correct class (square active)
            var CustName = CustomerNames.Where(cid => cid.ID == Convert.ToInt32(ddlName.SelectedValue)).FirstOrDefault();
            spName.InnerText = ddlName.SelectedItem.Text;

            // += on lit1.Text so that the span list is not empty. 
            // If i remove the lin SetNameHTML(CustomerNames); above then the list is empty
            lit1.Text = string.Format("<span class='square active' ID='spName' runat='server' data-value='{0}'>{1}</span> <br />", CustName.FirstName, CustName.ID);
        }
    }
}

ASPX 代码

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <span class="info" runat="server" id="spName"></span>
            <asp:DropDownList ID="ddlName" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlName_SelectedIndexChanged"></asp:DropDownList>
            <br />
            <div class="squares">
                <asp:Literal ID="lit1" runat="server"></asp:Literal>

            </div>
        </div>
    </form>
</body>
</html>

我正在使用文字控件,因此我可以根据找到的名称数量添加相关跨度。请注意,我删除了大部分 CSS JS,这就是为什么它看起来很普通。

当我从下拉列表中选择一个项目时,它会再次添加该项目(如果你运行上面的代码,你就会明白我的意思)

注意我的 cmets 以及为什么我做了我所拥有的。

这是页面加载时的视图源,然后我选择了一个项目

加载

<div class="squares">

<span class='square active' ID='spName' runat='server' data-value='Name 1'>1</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 2'>2</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 3'>3</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 4'>4</span> <br />

            </div>

选择的第一个项目

<div class="squares">

<span class='square active' ID='spName' runat='server' data-value='Name 1'>1</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 2'>2</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 3'>3</span> <br />
<span class='square' ID='spName' runat='server' data-value='Name 4'>4</span> <br />
<span class='square active' ID='spName' runat='server' data-value='Name 2'>2</span> <br />

            </div>

我知道为什么会这样,但我不知道该怎么做。我想要做的不是再次将所选项目添加到列表中,但由于我使用文字控件,我不知道如何删除它,或者是否有更好的方法来解决这个问题?

【问题讨论】:

  • 您可以尝试将跨度添加为实际控件,而不仅仅是在您的代码中添加一个 html 字符串,您可能会有更好的运气。像这样:var span = new System.Web.UI.HtmlControls.HtmlGenericControl("span"); 然后添加您的属性:span.Attributes.Add("data-value", c.ID); 然后只需将新的跨度控件添加到文字:lit1.Controls.Add(span);
  • 将文字改为占位符
  • 正如@pho3nix 所说,您可能应该使用占位符控件。 &lt;asp:PlaceHolder /&gt; 呈现为 &lt;div /&gt;,因此您应该将“正方形”div 替换为占位符,然后将跨度添加到其中。像这样:&lt;asp:PlaceHolder ID="phSquares" runat="server" CssClass="squares"&gt;
  • @zgood - 正如你所看到的,我已经发布了一个建议 PlaceHolder 的答案(事实上,在 pho3nix 的评论之前)。顺便说一句,PlaceHolder 不会呈现为 div。其内容在页面中呈现,无需额外的容器 (stackoverflow.com/questions/2743404/…)。
  • @ConnorsFan 是的,你是对的......我在想&lt;asp:Panel /&gt;。对不起,我没有看到你回答。在我上面的评论中,只需将“PlaceHolder”替换为“Panel”就可以了。

标签: c# html asp.net


【解决方案1】:

在添加值(或更改事件)之前检查它是否不存在

if (!ddlName.Items.Contains("ValueToAdd"))
{//add value in dropdown list}

希望对你有帮助

【讨论】:

  • 感谢您的回复。该项目将自身重新添加到文字控件中。不是下拉列表。
【解决方案2】:

您可以用 PlaceHolder 替换 Literal 控件:

<asp:PlaceHolder ID="ph1" runat="server" />

并在其中添加 ASP.NET Label 控件,这些控件在 HTML 输出中呈现为 span 元素,或 ASP.NET Panel 控件,它们呈现为 div 元素。

这样,您将使用控件而不是在 Literal 中插入原始 HTML 代码,这更难管理。

更新

新标签必须在每次回发时添加到 PlaceHolder,而不是在 if (!IsPostBack) 条件块内。每个 ID 也必须是唯一的(或者您可以将 ID 属性留空)。我之所以提到它,是因为我在您的标记示例中看到了几个 ID 为 spnamespan 元素。

在一个简单的例子中,它看起来像这样:

private int labelSuffix = 0;

protected void Page_Load(object sender, EventArgs e)
{
    Label lbl = new Label();
    lbl.ID = string.Format("span_{0}", labelSuffix++);
    lbl.Attributes.Add("data-value", "Name 1");
    lbl.CssClass = "square";
    lbl.Text = "1";
    ph1.Controls.Add(lbl);
    ...
}

然后可以在另一个事件处理程序中检索标签:

protected void btnPostBack_Click(object sender, EventArgs e)
{
    // By the ID of the control
    Label lbl = ph1.FindControl("MyLabel") as Label;
    lbl.Text = "With some new text";

    // Or by looping on the controls collection
    foreach (Label lbl in ph1.Controls)
    {
        lbl.Text = "And another text";
    }
}

【讨论】:

  • 使用占位符似乎有帮助!目前,我添加了一个标签,该标签分配的文本与我为文字控件所拥有的文本相同,并将其添加到 PH 控件集合中。目前的问题是,当我从 DD 中选择一个值时,即使在调试模式下的代码隐藏中我可以看到正在执行的行,它也不会改变 span 的值?
  • 我已经更新了我的答案以展示 PlaceHolder 的简单用法。
  • 谢谢!我尝试了一个运行良好的标签,但我遇到的标签问题是当它呈现它时添加了自己的跨度标签。即使我使用 Text 属性,我也无法在此标记中添加相关的跨度 HTML?因此,我更改为 Literal 控件,该控件再次正常工作,但控件的 ID 始终相同,即使我添加了新的 Literal 并设置了 ID。我会看看我是否可以按照你的建议修改页面加载,看看会发生什么。
  • 你可以让Label渲染它的span标签而不在它的内容中添加一个。这就是使用标签的想法:不必自己管理标签。只需设置 Text 属性并添加 data-value 属性。我再次更新了我的答案以表明这一点。我还展示了如何定义一个变量来确保每个标签的 ID 不同。
  • 谢谢!!这做到了。感谢您对此的耐心等待。
猜你喜欢
  • 1970-01-01
  • 2015-12-22
  • 2022-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-06
  • 1970-01-01
  • 2014-11-21
相关资源
最近更新 更多