MVC4 - Setting Initially Selected Item in DropDownList - c#

I am passing in a list of objects to my View via a model
#model MyModel.ObjectViewModel
I am new to MVC and am trying to set the initially selected item of a dropdownlist in my view (modelled after an Edit).
I am then binding this to a drop down list as follows
<label for="ddlObjects">Select Object</label>
#Html.DropDownList("ddlObjects", Model.AllObjectsSelectList, Model.Object.ObjectName)
The above does make the drop down list have the correct object selected initially, but I discovered it is only in the form of text. The real object isn't chosen and as such the value isn't used. How can I have a list of items, say, "Object1" "Object2", etc and have the default be a specific one?
When I'm passing through the item I only know the text value (the name that appears in the drop down list) of the item, I don't know it's inner value so I can't really use SelectListItem {Text = "X", Value= "Y"}
I have searched here and through google, and there are options for setting the intially selected value, however they are using methods like #Html.DropDownList for which doesn't seem to let me specify a control name, and in my controller I specifically reference the name of the control.

My work around wasn't pretty, but it could be easily refactored to be much nicer. It will just be a case of some effort which at present I don't have time for - but I will in the next week or so.
I created a method in my controller which I pass in my list of items (selectList, which you would think would work anyway... but it doesn't) then I work out which is the object I require and set the Selected property to true.
private List<SelectListItem> GetListOfObjectTypes(SelectList selectList, string objectTypeName, string objectTypeId)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (METAObjectType item in selectList.Items)
{
bool isSelected = false;
if (item.Name == objectTypeName)
{
isSelected = true;
}
items.Add(new SelectListItem {Selected= isSelected, Text=item.Name, Value=item.ObjectTypeId.ToString()});
}
return items;
}
I then just pass this through to my View and set it as the list in the #Html.DropDownList and it will now select the correct item by default.

Related

Selected property on SelectListItem not being set by SelectList constructor

I'm creating a SelectList to pass to a Html.DropDownList, but the correct value doesn't seem to be populating
var x = new SelectList(new[] {
new SelectListItem() { Value="1", Text="Vanilla"},
new SelectListItem() { Value="2", Text="Chocolate"},
new SelectListItem() { Value="3", Text="Strawberry"}
}, "Value", "Text", "2");
SelectList should take a constructor that takes in the selectedValue:
public SelectList(
IEnumerable items,
string dataValueField,
string dataTextField,
object selectedValue
)
But this only sets the SelectedValue on the entire collection. The individual SelectListItems haven't been set as Selected
Do I need to iterate over them individually and set selected for each as in this question?
The Selected property is being set by the SelectList constructor. The image you have shown is for the items argument (i.e the collection of SelectListItem that you passing to the method), not the result of calling the method.
The constructor does not modify the collection passed to it, it creates a new IEnumerable<SelectListItem>, and if you inspect the value of var x, then you will see that the 2nd SelectListItem (the one with Value = "2") will have its Selected property set to true.
However, the purpose of the SelectListItem class is for use in one of the HtmlHelper methods that generates a <select> (DropDownList(), DropDownListFor(), ListBox() and ListBoxFor() methods) which accept an IEnumerable<SelectListItem> as either the 1st or 2nd argument.
Unless you specifically not binding to a model property (e.g. #Html.DropDownList("NotAModelProperty", Model.YourSelectList)), then setting the Selected property is ignored because the method sets the selected option based on the value of the property your binding to (refer How to set “selectedValue” in DropDownListFor Html helper for more detail), therefore creating a new IEnumerable<SelectListItem> from the first one by using new SelectList(...) is pointless extra overhead.
The reason for using the SelectList constructor is to create an IEnumerable<SelectListItem> from an existing collection of objects, for example
IEnumerable<SelectListItem> options = new SelectList(db.Flavors, "ID", "Name")
which would get the records from the Flavors table, and set the Value based on its ID property, and the Text based on its Name property. It just provides an alternative to using (say)
IEnumerable<SelectListItem> options = db.Flavors.Select(x => new SelectListItem
{
Value = x.ID.ToString(),
Text = x.Name
});

DropDownListFor selectedItem not working as expected

I have s simple dropdown which is rendered with:
#Html.DropDownListFor(m => m.Request.Value, new SelectList(items, "Value", "Text", selectedElement), new {})
where Model.Request.Value is of type int and has the value set to -1.
items is build like:
var items = new List<SelectListItem<int>>();
items.Add(new SelectListItem<int>{Text = "10", Value = 10});
items.Add(new SelectListItem<int>{Text = "25", Value = 25});
items.Add(new SelectListItem<int>{Text = "100", Value = 100});
items.Add(new SelectListItem<int>{Text = "All", Value = -1});
The value of selectedElementis 25, which is of type int. However, it always renders the select with All selected, which means value = -1.
Why? And why is there a value selectedElement which get's overridden no matter what?
Your strongly binding to a property in your model, so its the value of the property that determines what is selected. That's how model binding works. If you want "All" to be selected, set the value of Request.Value = -1
The 4th parameter of the SelectList constructor is ignored when binding to a property. The only time it is respected is if you were to use something like #Html.DropDownList("NotAPropertyOfMyModel, new (SelectList(...
Side note: items is IEnumerable<SelectListItem> (which is what the DropDownListFor() method requires) so creating a new IEnumerable<SelectListItem> (which is what SelectList is) is just pointless extra overhead. Your view should be just
#Html.DropDownListFor(m => m.Request.Value, items)
DropDownListFor uses the value of lambda expression to select the item in the dropdown list rather than the last argument of the SelectList constructor.
I believe that the following link includes sample code that should be able to help you:
MVC DropDownList SelectedValue not displaying correctly

adding an additional item to a listbox

I am having a difficulty adding an item to my listbox. I want to add an item at the beginning of the list box to be my 'default' item, however I will also be adding a list of items from a List using the .DataSource ... and for some reason the app is crashing whenever I try to add the items from the List and the default item at the same time. I am trying to add the items by using:
`productList.DataSource = salesManager.Products;
productList.DisplayMember = "IdAndName";
productList.ValueMember = "Id";
productList.Items.Insert(0, "ALL");`
but for some reason VS will not let me. I have also found this method and tried to apply it as well:
public void AddListLine(string lineIn)
{
productList.Items.Insert(0, "ALL");
((CurrencyManager)productList.BindingContext[productList]).Refresh();
}
However it is not working as well. Any idea please? Thanks!
The reason it isn't working is because you are attempting to add an object of type String where the rest are (I assume) of type Product or something similar. The runtime attemps to access the property IdAndName to display and the property Id for the display and value properties of the new list item and they do not exist.
Consider adding some kind of "blank" Product object instead.
public void AddListLine(string lineIn)
{
productList.Items.Insert(0, new Product { Id = "ALL", IdAndName = "ALL" });
((CurrencyManager)productList.BindingContext[productList]).Refresh();
}

ListItem's value gets replaced by the text on DataBind

I'm at a bit of a loss on this one and haven't been able to find anything helpful in my searches so I'm hopeful someone can help me out here.
I've got a RadioButtonList that I'm adding a List of dynamically created ListItems, where I set both the text and the value for each item. On DataBind for the RadioButtonList the Value for the ListItem gets replaced by the Text, which just doesn't seem to make sense to me.
I can see on the client side when I look in Firebug that the label and the value on the input are the same, and the value is nowhere to be seen.
Has anyone else had any experiences like this, or does anyone know where I might be going wrong?
var rbList = new List<ListItem>();
var radioButtonList = new RadioButtonList();
foreach(var object in objects) {
var li = new ListItem {Text = object.Name, Value = object.Guid};
rbList.Add(li);
}
radioButtonList.DataSource = rbList;
radioButtonList.DataBind();
Should you be using Databinding here? Can you not just add your ListItems to the radio button list directly?
I would imagine that the Databinding is getting confused about how to bind your list so is just using ToString on each of your elements which seems to just return the Text Property. This is then being used as both the Text and the Value.
You probably just want to create your items and add them straight to your Radio button control as follows:
var radioButtonList = new RadioButtonList();
foreach(var object in objects) {
var li = new ListItem {Text = object.Name, Value = object.Guid};
radioButtonList.Items.Add(li);
}
For those, whose are still struggling - do not forget to fill DataValueField, if control has it. Simply provide string name of your value property and you will be fine.
As Chris mentioned - Databinding was in fact confused and therefore DataValueField exists. My problem was with basic asp:DropDownList.

Setting default item in combo box

I have a function for setting items in a combobox and one item is to be set by default like
--SELECT LIST--
public void SetOperationDropDown()
{
int? cbSelectedValue = null;
if(cmbOperations.Items.Count == 0)
{
//This is for adding four operations with value in operation dropdown
cmbOperations.Items.Insert(0, "PrimaryKeyTables");
cmbOperations.Items.Insert(1, "NonPrimaryKeyTables");
cmbOperations.Items.Insert(2, "ForeignKeyTables");
cmbOperations.Items.Insert(3, "NonForeignKeyTables");
cmbOperations.Items.Insert(4, "UPPERCASEDTables");
cmbOperations.Items.Insert(5, "lowercasedtables");
//ByDefault the selected text in the cmbOperations will be -SELECT OPERATIONS-.
cmbOperations.Text = "-SELECT OPERATIONS-";
}
else
{
if(!string.IsNullOrEmpty("cmbOperations.SelectedValue"))
{
cbSelectedValue = Convert.ToInt32(cmbOperations.SelectedValue);
}
}
//Load the combo box cmbOperations again
if(cbSelectedValue != null)
{
cmbOperations.SelectedValue = cbSelectedValue.ToString();
}
}
Can anyone suggest a way to do this?
I've rewritten this answer to clarify some stuff.
First, the "default" text must be added as combo item as well.
Usage of combo.Text property just adds descriptive text to combobox which is "lost" first time user do something with a control.
If you like to permanently have "default" text in your combo, you must add it as an combobox item.
By the code you provided, just modify the
cmbOperations.Text = "-SELECT OPERATIONS-"; to
cmbOperations.Items.Insert(0, "-SELECT OPERATIONS-");
Note that this way you add the item "-SELECT OPERANDS-" to the 0th (read first) position in the list.
Also make sure that all your following items are increased by 1, because they are now moved by one space down in list.
Finally, put cboOperations.SelectedIndex = 0; line at the end of code. By doing so, you're telling combobox to display your "default" item initially when the form (or control) loads.
One more thing. I'm not pretty sure what do you want to achieve with the code beyond setting combo items, but if you like to check what user selected use cboOperations.SelectedIndex property which contains currently selected item in combo. You can add simple if(cboOperations.SelectedIndex == someIntValue){...}
The rest is your program logic ;)

Categories