On my ViewData I have a property name Target of type string which I want the user to select from one of the possible targets.
So I added a new property to my ViewData named Targets, of type SelectList, that holds the possible targets.
Now what I need is, on my view, display a DropDownList with all items from Targets and where the selected item is the one which value is contained in Target.
On my controller:
var dict = new Dictionary<string, string>();
dict.Add("Blank", "_blank");
dict.Add("Parent", "_parent");
dict.Add("Self", "_self");
dict.Add("Top", "_top");
viewData.Targets = new SelectList(targets);
Well... probably you mistyped some variable name, but this was not the real problem.
You must tell the SelectList how to bind the list and which property of the object is used for the text and which for the data, so, since each element in the dictionary is a KeyValuePair the controller should be:
public ActionResult SelectSample()
{
var dict = new Dictionary<string, string>();
dict.Add("Blank", "_blank");
dict.Add("Parent", "_parent");
dict.Add("Self", "_self");
dict.Add("Top", "_top");
ViewData["Targets"] = new SelectList(dict,"Value","Key");
return View();
}
Then the DropDownList can also be called with the easy overload:
<%= Html.DropDownList("","Targets") %>
The easy overload automatically probes both the ViewData dictionary and the model, so no need to do all the conditional binding you are doing in your code.
While all the other html form controls have to bind only one data, the DropDownList has to select two different data: the list of items and the selected item.
From the API it's not easy to understand, but using one overload you decide to automagically bind the list of items and with the other overload you decide to bind the selectedItem.
The overload with only the name binds the list of items (and the name must be the name of list in the viewdata)
<%= Html.DropDownList(null,"Targets") %>
The other overload, that gets also the SelectList as parameter, binds the selected item(and the name must be the selected item)
but this works: <%= Html.DropDownList(null, "Targets") %> . This is what I don't get ...
On my controller I have:
public ActionResult Create() {
SlideViewData viewData = new SlideViewData();
viewData.Targets = Asset.Targets();
viewData.SlidePaper.Slide.Target = "_blank";
return View("Create", viewData);
}
I am testing this on my Create view but as you can see I am defining Targets and Target.
Asset.Targets is:
public static SelectList Targets() {
var targets = new Dictionary<string, string>();
targets.Add("Blank", "_blank");
targets.Add("Parent", "_parent");
targets.Add("Self", "_self");
targets.Add("Top", "_top");
var list = new SelectList(targets, "Value", "Key");
return list;
}
the problem is that your "Target" property is not at root level, but is nested inside SlidePaper.Slide.Target, so the automagic binding doesn't find it.
shapper
Contributor
3932 Points
3789 Posts
DropDownList ... What am I doing wrong?
Sep 15, 2008 08:57 PM|LINK
Hello,
On my ViewData I have a property name Target of type string which I want the user to select from one of the possible targets.
So I added a new property to my ViewData named Targets, of type SelectList, that holds the possible targets.
Now what I need is, on my view, display a DropDownList with all items from Targets and where the selected item is the one which value is contained in Target.
On my controller:
var dict = new Dictionary<string, string>(); dict.Add("Blank", "_blank"); dict.Add("Parent", "_parent"); dict.Add("Self", "_self"); dict.Add("Top", "_top"); viewData.Targets = new SelectList(targets);Then on my view I have:
<%= Html.DropDownList("", "Targets", ViewData["Targets"] ?? ViewData.Model.Targets) %>What I see in my DropDownList is:
[Blank, _blank], [Top, _top], ...
What am I doing wrong?
And how can I set the default value of the DropDownList to be the value contained in ViewData["Target"]
Thank You,
Miguel
Ai_boy
Member
2 Points
1 Post
Re: DropDownList ... What am I doing wrong?
Sep 15, 2008 11:10 PM|LINK
<%= Html.DropDownList(String.Empty, "Targets", (Dictionary<string, string>)(ViewData["Targets"] ?? ViewData.Model.Targets))%>
simonech
Member
344 Points
136 Posts
MVP
Re: DropDownList ... What am I doing wrong?
Sep 15, 2008 11:34 PM|LINK
Well... probably you mistyped some variable name, but this was not the real problem.
You must tell the SelectList how to bind the list and which property of the object is used for the text and which for the data, so, since each element in the dictionary is a KeyValuePair the controller should be:
public ActionResult SelectSample() { var dict = new Dictionary<string, string>(); dict.Add("Blank", "_blank"); dict.Add("Parent", "_parent"); dict.Add("Self", "_self"); dict.Add("Top", "_top"); ViewData["Targets"] = new SelectList(dict,"Value","Key"); return View(); }Then the DropDownList can also be called with the easy overload:
The easy overload automatically probes both the ViewData dictionary and the model, so no need to do all the conditional binding you are doing in your code.
HTH
Simo
shapper
Contributor
3932 Points
3789 Posts
Re: DropDownList ... What am I doing wrong?
Sep 15, 2008 11:47 PM|LINK
But how to I "tell" the DropDownList which value is the selected one?
ViewData["Target"] holds that value and in taken from a database so on Edit view I want the DropDownList to be on that value.
Thanks,
Miguel
simonech
Member
344 Points
136 Posts
MVP
Re: DropDownList ... What am I doing wrong?
Sep 16, 2008 09:22 AM|LINK
You have to specify it when you create the SelectList object:
It's a bit inconsistent with how the other controls are bound.
simonech
Member
344 Points
136 Posts
MVP
Re: DropDownList ... What am I doing wrong?
Sep 16, 2008 09:48 AM|LINK
Did a bit more of testing.
While all the other html form controls have to bind only one data, the DropDownList has to select two different data: the list of items and the selected item.
From the API it's not easy to understand, but using one overload you decide to automagically bind the list of items and with the other overload you decide to bind the selectedItem.
The overload with only the name binds the list of items (and the name must be the name of list in the viewdata)
The other overload, that gets also the SelectList as parameter, binds the selected item(and the name must be the selected item)
Hope this answers your question, and also the question asked by timtas in the other thread (http://forums.asp.net/t/1320461.aspx)shapper
Contributor
3932 Points
3789 Posts
Re: DropDownList ... What am I doing wrong?
Sep 16, 2008 11:25 AM|LINK
That does not solves it ... That was I had tried before I post this thread. If I use:
<%= Html.DropDownList(null, "Target", ViewData["Targets"] ?? (SelectList)ViewData["Targets"]) %>
I get the error:
There is no ViewData item with the key 'Target' of type 'System.Web.Mvc.SelectList'.
Then I try yours:
I get the error:
Value cannot be null.
Parameter name: selectList
Use the "new" keyword to create an object instance
Not sure what is going on.
Thanks,
Miguel
simonech
Member
344 Points
136 Posts
MVP
Re: DropDownList ... What am I doing wrong?
Sep 16, 2008 11:40 AM|LINK
I think both fail because there is no ViewData["Targets"] created in you action.
If the action is the code you wrote in the first message, you wrote viewdata.Targets which doesn't exist (actually it should even not compile).
In order to make it work you need two elements in the ViewData:
ViewData["Targets"] which contains the list of items.
ViewData["Target"] which contain the selected item.
If this doesn't solve the problem, can you please post the full action?
Simo
shapper
Contributor
3932 Points
3789 Posts
Re: DropDownList ... What am I doing wrong?
Sep 16, 2008 12:12 PM|LINK
Hi,
but this works: <%= Html.DropDownList(null, "Targets") %> . This is what I don't get ...
On my controller I have:
public ActionResult Create() { SlideViewData viewData = new SlideViewData(); viewData.Targets = Asset.Targets(); viewData.SlidePaper.Slide.Target = "_blank"; return View("Create", viewData); }I am testing this on my Create view but as you can see I am defining Targets and Target.
Asset.Targets is:
simonech
Member
344 Points
136 Posts
MVP
Re: DropDownList ... What am I doing wrong?
Sep 16, 2008 12:25 PM|LINK
OK, I got it..
the problem is that your "Target" property is not at root level, but is nested inside SlidePaper.Slide.Target, so the automagic binding doesn't find it.