I have a drop down list control populated with items and some code to take the currently selected item value. The problem is I only get the value of the first item in the list regardless of what item is actually selected.
Here is my code to populate the drop down:
protected void displayCreateCategories()
{
StoreDataContext db = new StoreDataContext();
var a = from c in db.Categories
orderby c.Name
select new{catName= c.Name,
catId=c.CategoryID};
ddlCategory.DataSource = a;
ddlCategory.DataTextField = "catName";
ddlCategory.DataValueField = "catId";
ddlCategory.DataBind();
}
To get the value of the currently selected item which in my case is always of type integer I do label1.text=Convert.toInt32(ddlCategory.SelectedValue);
I get the selected value, but it is always for the 1st item in the list. I'm pulling my hair out over this. :(
I suspect you're running the list loading code every time the page loads, which is destroying the list, repopulating the list, and auto-selecting the first item before your selection retrieval code gets run.
Use this construction in Page_Load:
if (!IsPostBack)
{
// Initial control population goes here
}
Data binding will reset the control's selected value so make sure you retrieve the selected value before data binding on postback.
Related
I have a form that takes in an object in it's constructor and populates controls on the form from properties in that object. I am having an issue where I can't set a ComboBox's SelectedText property, or at least it isn't working how I expect it to.
public Form(ValueHoldingObject obj)
{
// yeah I know this is not a very clean way to populate the combobox, the issue
// isn't limited to the combobox so I don't think this is relevant
List<int> items = Repo.GetAllItems().Reverse();
foreach (int id in checkInPrizeIds.Take(100))
// Insert at beginning to put more recently used items at the top
combobox.Items.Insert(0, id);
combobox.DropDownHeight = 200;
combobox.SelectedText = obj.StringProperty;
}
When I am testing this form the text of the combobox isn't being populated. If I add a breakpoint on the line where I assign the text it DOES get assigned, so some event is firing (multiple focus change events probably) and making it work the way I want. Obviously I can't use a breakpoint as a fix in production code. Am I assigning this value incorrectly? Should I be using a different method to populate the values?
Further testing has reviled that it isn't just the combobox, all of my controls are only being populated correctly if I have the breakpoint.
In the constructor, you need to set the selected item, for example:
foreach ( var item in combobox.Items )
if ( (string)item == obj.StringProperty )
combobox.SelectedItem = item;
Or:
foreach ( var item in combobox.Items )
if ( (int)item == Convert.ToInt32(obj.StringProperty) )
combobox.SelectedItem = item;
It's confusing but despite its name, the property SelectedText is not really the selected item... because combo box items are objects and not strings: texts shown are a representation of the item objects using ToString().
Therefore setting the selected text will not guarantee to select an item and we can prefer setting the SelectedItem.
In addition to these considerations, you set the selected text property in the constructor after populating the combo box and that can cause problems because it is before the form and the control are drawn or something like that... that is to say perhaps before the ToString() methods are called on items to prepare the visual cache, so setting the selected text can't get a match with the list.
Setting the selected text selects an existing item if done in the form load or shown events.
private void Form_Load(object sender, EventArgs e)
{
combobox.SelectedText = obj.StringProperty;
}
ComboBox.SelectedText doesn't give me the SelectedText
ComboBox.SelectedText Property
I have a small project where I get some values from a txt and put inside of a ListView. I need to get the selected value when I click in some item, the first item that I ever select, works fine, but if I try to select again, I get an exception.
This is what I did..
Json = new StreamReader(openDialog.FileName).ReadToEnd();
var ParsedValue = JsonValue.Parse(Json);
Parsed = JsonConvert.DeserializeObject<List<Model>>(ParsedValue.ToString());
foreach (var item in Parsed)
{
var rows = new string[] { item.car, Convert.ToString(item.age )};
var items = new ListViewItem(rows)
{
Tag = item
};
ListViewCars.Items.Add(items);
}
The List view is Filled.
And to get the Item selected from the list :
private void cartsList_SelectedIndexChanged(object sender, EventArgs e)
{
ItemSelected = (Model)ListViewCars.SelectedItems[0].Tag;
}
I can only get the value that I select first when the program runs.
The exception :
System.ArgumentOutOfRangeException: 'InvalidArgument=Value of '0' is not valid for 'index'.
Parameter name: index'
Check out the documentation on ListView.SelectedIndexChanged. Specifically, look at the Remarks section, which reads:
The SelectedIndices collection changes whenever the Selected property of a ListViewItem changes. The property change can occur programmatically or when the user selects an item or clears the selection of an item. When the user selects an item without pressing CTRL to perform a multiple selection, the control first clears the previous selection. In this case, this event occurs one time for each item that was previously selected and one time for the newly selected item.
I added the emphasis. This means that when you select the second item, the currently selected item is unselected and SelectedIndexChanged is triggered before the new item is selected. So when you try to get the first selected item with ListViewCars.SelectedItems[0].Tag you get that ArgumentOutOfRangeException because there are no selected items.
You need to add a check to the top of your event handler to make sure that there is at least one selected item before accessing SelectedItems[0].
for (int i = 0; i < lboxavilableInsName.Items.Count; i++)
{
if (lboxavilableInsName.Items[i].Selected)
{
if (!arraylist1.Contains(lboxavilableInsName.Items[i]))
{
arraylist1.Add(lboxavilableInsName.Items[i]);
arrUpdatedInsValues.Add(lboxavilableInsName.Items[i].Value);
arrUpdatedInsNames.Add(lboxavilableInsName.Items[i].Text);
}
ViewState["UpdatedInsValues"] = arrUpdatedInsValues;
arrUpdatedInsValuestotal = (ArrayList)ViewState["UpdatedInsValues"];
ViewState["UpdatedInsValues2"] = `enter code here`arrUpdatedInsValuestotal;
ViewState["UpdatedInsNames"] = arrUpdatedInsNames;
}
}
Actually I have given selsectionmode="Multiple" in the listbox. That will select me multiple items when I select first time or subsequent time after page gets loaded, but I want that in a code behind saying ex: if I select 2 items 1st time that 2 items will added in the second listbox and I will get the values of those selected items.
If again I select any items after adding previous selection items in 2nd listbox, I want the item value selected at 2nd time along with first two item values. So totally 3 values I want. and I need to send that values to the stored procedure to insert.
Its because you are assigning new values each time to the 2nd listbox, you don't need to assign them, you need to add values within your 2nd listbox, in this way your 2nd listbox will retain all the previous and the new values as well.
Hope it helps.
i have two nested drop down list.
one drop down show group,the other show sub group.
i have coded data source of subgroup drop down list on group drop down list selected indexed change event.
What I'm trying to do is set a drop down list to be whatever its value is in the database when editing an entry.
i have used data row.
i have two tables.documentgroup(GroupId,parentId,groupTitle,subGroupTitle) and documents(DocID,GroupID,Title,url)
in my drop down lists i have added list item like this
<asp:ListItem Text = "--select group--" Value = ""></asp:ListItem>
when i click on editing a document,i have this.
protected void grdDocuments_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DoEdit")
{
GC.Collect();
GC.WaitForPendingFinalizers();
int DocID = Convert.ToInt32(e.CommandArgument);
ViewState["DocumentID"] = DocID;
ViewState["EditMode"] = "Edit";
DataTable dtDocuments = DataLayer.Documents.SelectRow(DocID).Tables["Documents"];
if (dtDocuments.Rows.Count != 0)
{
DataRow drDocuments = dtDocuments.Rows[0];
txtDocTitle.Text = drDocuments["DocTitle"].ToString();
txtDocPubYear.Text = drDocuments["DocPubYear"].ToString();
ddlDocGroupTitle.SelectedValue = drDocuments["ParentID"].ToString();
ddlDocSubGroupTitle.SelectedValue = drDocuments["DocGroupID"].ToString();
ViewState["DocCurrentUrl"] = drDocuments["DocUrl"].ToString();
mvDocuments.SetActiveView(vwEdit);
}
}
but i get this error
'ddlDocSubGroupTitle' has a SelectedValue which is invalid because it
does not exist in the list of items. Parameter name: value
and this is the same for ddldocgroupTitle.
i have made an inner join between two tables.
what should i do?
I could not really grasp your question, but it looks like you want to have 2 dropdown, and upon selection in the first, the second gets populated/filtered correct?!?
I recommend that you use javascript/Jquery to do so. Upon page load, issue a ajax get request to fill the "main" dropdown, and upon selection on the first one, you issue a second ajax request to fetch the possible values of the second one...
A alternative is to fetch the items for the first dropdown AND all the values possible for the second, storing the result in some hidden-field data. Then upon selection of the first value, you can only filter + display relevant data.
So i am getting this error
{"'drpButton1' has a SelectedValue which is invalid because it does not exist in the list of items.\r\nParameter name: value"}
From everything i can read this is because the DropDownList either had existing items or had a selected index or value which is not in the new databound items.
But the thing is i can GUARANTEE that there are no existing items in the object and i can also say with confidence that there has not been an index selected that could be out of range.
Here is what the DropDownList object looks like directly before the .databind() call.
Here it is directly after the databind() call that has caused all the explosions.
My list object contains 7 items and in particular it contains the item that the databind method randomly decides to pick.
But here is the kicker i literally fill up 8 dropdowns with the EXACT same data and it works on the first dropdown just fine. No idea why the second one explodes.
EDIT: here is the code that does the binding:
Here is a snippet from the load method. the first call succeeds the second one fails but it doesn't fail all the time.
private void LoadShortCodeDropDownData()
{
// Initilization junk to get the resultList to use.
base.LoadListDropDown(drpButton0, (IList)resultList, "DeviceShortCodeIndexID", "DeviceShortCodeName", select);
MessageTextEnabled(drpButton0);
base.LoadListDropDown(drpButton1, (IList)resultList, "DeviceShortCodeIndexID", "DeviceShortCodeName", select);
MessageTextEnabled(drpButton1);
}
protected void LoadListDropDown(DropDownList dropDown, IList list, string valueField, string textField, string insertItem)
{
LoadListDropDown(dropDown, list, valueField, textField);
//dropDown.Items.Insert(0, new ListItem(insertItem, ""));
}
protected void LoadListDropDown(DropDownList dropDown, IList list, string valueField, string textField)
{
dropDown.DataSource = list;
dropDown.DataValueField = valueField;
dropDown.DataTextField = textField;
dropDown.DataBind();
}
EDIT2: I think the real question i have here is how is the databind picking which item to select? I noticed that the first dropdown that gets databound randomly selects the first value in the list while the second one tries to bind to the very last one in the list for some reason.
Is this happening on the first load of the page, or after a postback? Because if it's a postback, you very well could have SelectedIndex == 0 just by default.
I can't guarantee that this will solve the problem, but you could try adding
dropDown.SelectedIndex = -1;
... to the top of your second LoadListDropDown overload.
I've run in to this before, and I dont think you can bind the same list to multiple drop downs.