views:

180

answers:

3

Is there a way to determine (after a postback) if a value in a dropdownlist has been added dynamically or is one of the initial values?

eg.

<asp:DropDownList ID="MyDDL" runat="server">
  <asp:ListItem>1</asp:ListItem>
  <asp:ListItem>2</asp:ListItem>
  <asp:ListItem>3</asp:ListItem>
</asp:DropDownList>

// on postback 1
private void AddExtraItemToList()
{
    if (someCondition) // extra items may or may not be inserted
        MyDDL.Items.Add("17");
}


// on postback 2
private void RemoveExtraItemsFromList()
{
    // remove any non-default values from the list... ?
}

It's obvioulsy trivial to do by coding a list of default values in code behind or something, but it would be neat if you could do the above by querying which values were intial properties and which were generated from viewstate restoration.

A: 

Hai ,

Have a look at this Clear Dropdown values other than default value

Pandiya Chendur
That question does not deal with the same problem - the one to keep is known (i.e. the first one). In this situation, there needs to be some other way to identify which items to keep and which to remove.
Jason Berkan
+1  A: 

You could give the list items identical values based upon whether they were original items or extra items.

<asp:DropDownList ID="MyDDL" runat="server">
    <asp:ListItem Value="A">1</asp:ListItem>
    <asp:ListItem Value="A">2</asp:ListItem>
    <asp:ListItem Value="A">3</asp:ListItem>
</asp:DropDownList>

private void AddExtraItemToList() {
    if (someCondition) // extra items may or may not be inserted
        MyDDL.Items.Add(new ListItem("17", "B");
}

private void RemoveExtraItemsFromList() {
    for (int x = MyDDL.Items.Count - 1; x > 0; --x) {
        if MyDDL.Items[x].Value = "B" {
            MyDDL.Items.RemoveAt(x);
        }
    }
}

Sorry if there are C# syntax errors - I'm a little rusty and translating from VB.

Jason Berkan
+1, neat idea, though it still feels a bit hacky
fearofawhackplanet
It is - not sure there is a simple non-hack solution. Obviously, if you require the use of the value, then this solution will not work at all.
Jason Berkan
+1  A: 

The best way to handle this is to keep track of the original values in your code from the start.

Here is an adapted version of your code that does this by storing the originals in viewstate (you can store them anywhere). The trick is that you have to pull out the items in the dropdown BEFORE you do any dynamic inserts for new items.

        public string[] OriginalDropDownValues
        {
            get
            {
                return ViewState["origValues"] as string[];
            }
            set
            {
                ViewState.Add("origValues", value);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                // get the values from the control and store them in viewstate
                var oValues = new List<string>();
                foreach (ListItem item in MyDDL.Items)
                {
                    oValues.Add(item.Value);
                }
                OriginalDropDownValues = oValues.ToArray();
            }
        }

        // on postback 2
        private void RemoveExtraItemsFromList()
        {
            List<string> valuesToKill = new List<string>();
            var oItems = OriginalDropDownValues;
            foreach (ListItem currentItem in MyDDL.Items)
            {
                if (!oItems.Contains(currentItem.Value))
                {
                    // can't remove items yet, would modify collection we are iterating through
                    valuesToKill.Add(currentItem.Value);

                }
            }
            foreach (var killVal in valuesToKill)//loop kill values and locate+remove each from drop down.
            {
                MyDDL.Items.Remove(MyDDL.Items.FindByValue(killVal));
            }
        }
Stephen M. Redd