可以从Literal中删除标记项

时间:2016-06-17 13:57:56

标签: c# html asp.net

我有以下代码

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,这就是为什么它看起来很简单。

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

请注意我的评论以及为什么我已经完成了我的工作。

继承页面加载时的视图来源,然后选择项目

加载

<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>

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

2 个答案:

答案 0 :(得分:1)

您可以使用PlaceHolder替换Literal控件:

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

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

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

<强>更新

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

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

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);
    ...
}

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

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";
    }
}

答案 1 :(得分:0)

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

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

希望这有帮助