Dynamically update dropdownlist - asp.net

I have this dropdownlist populated and everything. The only problem is that whenever I add a new item in the database through my website, the dropdownlist doesn't update for some reason.
private CurrentUser _cu = new CurrentUser();//just to check if use is an admin or not.
protected void Page_Load(object sender, EventArgs e)
{
_cu = (CurrentUser)Session[Common.SessVariables.CurUser];
if (!_cu.CanReport) { Response.Redirect("~/default.aspx"); }
CurrentUser cu = (CurrentUser)Session[Common.SessVariables.CurUser];
if (!IsPostBack)
{
foreach (PrefixAdd loc in cu.Prefix)//Prefix is a Property
{
ListItem x = new ListItem(loc.Prefix);
PrefixID.Items.Add(x);
}
}
}
#Wayne I'm using a store procedure to just insert a Prefix like Pre,yes,sey, etc. Then the list is populated with prefixes.
StringBuilder sbSQL = new StringBuilder(255);
sbSQL.Append(string.Format("exec insPrefix #Prefix=N'{0}';", PrefixBox.Text.Trim()));
string msg = string.Empty;
msg = (_oDAW.ExecuteNonQuery(sbSQL.ToString())) ? string.Format(Common.GetAppSetting(Common.ConfigKeys.User_Submit_Success),
PrefixBox.Text.Trim()) : Common.GetAppSetting(Common.ConfigKeys.SubmitFail); //this is a somewhat custom method for CS and databinding.
# Yuriy Rozhovetskiy Yea I add new items to this page with the dropdownlist.

Whenever you add an item to your database, you have to rebind your drop down list.
yourDropDown.DataSource = //...
yourDropDown.DataBind();
That is, DropDownLists (and other controls) have no way of knowing that their data has changed behind the scenes, they can't automatically detect it. You have to tell the controls to rebind their data manually.
Good job on the Page_Load(...){ if !(IsPostback) part.

Since you add new prefix on this page with some postback item you need to add this new item to PrefixID dropdown's Items collection and update the CurrentUser instance in Session right after you have add new prefix to database.

Related

Sorting a gridview using a datatable, and datasource that is an ArrayList

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sorting.aspx
This article deals with creating a datatable first, then creating a gridview from it, to aid in sorting. My predicament is slightly different.
I have a Gridview, that on Page_Load, I set the datasource to an ArrayList, and bind.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.GridView1.DataSource = RequestManager.Instance.GetAllRequests();
this.GridView1.DataBind();
}
}
Now I would like to sort this GridView, so on the aspx page, I set AllowSorting="true", and OnSorting="GridView1_Sorting". So far, so good. I have the SortExpressions set in the BoundFields, and when I click on it, I know the _Sorting event is triggered.
Now, since this is a postback operation, I cannot simply cast the datasource of the gridview to a DataTable to sort. Saving to ViewState is an option, but I cannot figure out how to do it.
I would like to use the simple solution on this page, except for the DataTable not being available to me. Thanks for looking.
If you're able to target .NET v3.5, I recommend using Linq. In your _Sorting event handler, get the array list you did in the Page_Load and rebind it.
For example, if the type contained in the array list are MyType instances that have properties named Default and SomeField:
protected void Grid_Sorting(object sender, GridViewSortEventArgs e)
{
Func<MyType, object> keySelector;
if(e.SortExpresion == "SomeField")
{
keySelector = dataItem => dataItem.SomeField;
}
else
{
keySelector = dataItem => dataItem.Default;
}
ArrayList dataItems = RequestManager.Instance.GetAllRequests();
this.GridView1.DataSource = dataItems.OfType<MyType>().OrderBy(keySelector);
this.GridView1.DataBind();
}
That will get you started, then later inspect the sort expression to see if it ends with ASC or DESC and conditionally call .OrderByDescending(keySelector).
Finally, I don't recommend stashing the list in ViewState, as the ObjectStateFormatter is only optimized for a handful of types. http://msdn.microsoft.com/en-us/library/system.web.ui.objectstateformatter.aspx
Maybe consider ASP.NET cache instead.

Positioning of DDL items?

i have a dropDownList which gets its data from a database. Now after the data has bound, i programmatically add another listItem to the ddl, like so:
protected void ddlEffects_DataBound(object sender, EventArgs e)
{
DropDownList ddl = dwNewItem.FindControl("ddlEffects") as DropDownList;
ddl.Items.Add(new ListItem("","0")); //Adds an empty item so the user can select it and the item doesnt provide an effect
}
It all works, but the problem is that the newly added listItem appears at the bottom of the DDL. I want it to be the first item. I tried making the value 0, but its still at the bottom. Is there any way to put it at the top?
Thanks!
Check into the ddl.Items.Insert method that will allow you to insert items at a specific location.
Like this for example:
using (Entities db = new Entities())
{
ddlDocumentTypes.DataSource = (from q in db.zDocumentTypes where (q.Active == true) select q);
ddlDocumentTypes.DataValueField = "Code";
ddlDocumentTypes.DataTextField = "Description";
ddlDocumentTypes.DataBind();
ddlDocumentTypes.Items.Insert(0, "--Select--");
ddlDocumentTypes.Items[0].Value = "0";
}
Which using EF loads the DDL with items for the database, and then inserts at position zero a new item.

persist dropdownlist on paging

I have a GridView and I populate it via a List . One of its columns is a DropDownList and AllowPaging is set to true. My problem is when I choose a value on the ddl and after a paging the selected value is lost. Is there any way/idea to persist the selected values?
Thanks for your help.
You could use a Dictionary object within view state to save multiple values i.e.
Dictionary<int, string> ddlValues = new Dictionary<int, string>()
where int is the row index and string is the ddl selected value. Of course this could be an int/guid or whatever depending on the actual value stored in the ddl or an int if you want to work with selectedIndex instead.
on the page event you would need to do
protected void MyGridView_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
for(int rowIndex = 0; rowIndex < myGridView.Rows.Length; rowIndex++)
{
DropdownList ddl = myGridView.Rows[rowIndex].FindControl("ddlId") as DropDownList
if(ddl != null)
{
if(ddl.SelectedIndex > 0) //.. or sensible check appropriate to you
{
int ddlIndex = rowIndex * e.NewPageIndex + 1;
//.. add pageIndex and selectedValue to dictionary
ddlValues.Add(ddlIndex, ddl.SelectedValue);
}
}
}
}
Don't worry about the current page ddl values. These will be persisted with viewstate in the normal way. It is the 'hidden' pages that we are accounting for. Hence we are repopulating the dictionary when the grid pages.
The Dictionary could then be saved in session/viewState and used to rehydrate the dropdownlist by doing the process in reverse. For instance when the page loads (checking !isPostBack) or when the grid rebinds depending on exactly how you have set things up
You will probably want to persist the Data in the ViewState. Check out this MSDN article
http://msdn.microsoft.com/en-us/library/ms972976.aspx
After you save it in the ViewState, you can retrieve the data on PostBack like this:
if (!Page.IsPostBack)
{
//do some stuff
}
else
{
//retrieve the viewstate information
selectedValue= ViewState["dropdownlistValue"].ToString();
}
Alternatively, you could also maintain the information in a Session variable but that may introduce other issues depending on what exactly you are doing.

Making GridView Respond to 2 Drop Down Lists

I have got 2 DropDownLists on my Form and 1 GridView. I want the GridView to display the data according to the selection from the DropDownLists.
For Example, One DropDownList contains Names and another contains Dates. Both the DropDownLists can post back. So if I select a name from 1st DropDownList, the GridView should show all the results according to that Name. Similarly if i select the Date from the other DropDownList , the GridView should show the results according to the dates. But i cant figure out as how to bind GridView to respond to 2 DropDownList.
BTW i am binding both the Drop Down Lists and the Grid View to the DataSource Objects, which is getting data from the database.
Any Suggestions??
It's better and cleaner if You use two DataSource with selecting data from db, and binding each of them to the DropDownList. I tried in my ASP.NET app do what You want but unfortunatelly I have erorrs :/
My only sollution is to don't use DataSouce in aspx file, but in DropDownList SelectedItem event use DataContext and it's possible that then you could bind both to the same DataView like below. I am not sure, but maybe You must use null in DataSource to reset GridView before use new data source:
protected void btPokaz_Click(object sender, EventArgs e)
{
DataClassesDataContext db = new DataClassesDataContext();
var DzieciGrupa = from p in db.Dzieckos
where p.Grupy.Numer == Convert.ToInt32(this.dropListGrupy.SelectedValue)
orderby p.Nazwisko
select new { p.Imie, p.Nazwisko };
if (DzieciGrupa.Count() == 0) this.Label1.Text = "W " + this.dropListGrupy.SelectedValue.ToString() + " grupie nie ma dzieci zapisanych!";
this.GridGrupy.DataSource = null;
this.GridGrupy.DataSource = DzieciGrupa;
// this.GridView1.DataSourceID = String.Empty;
this.GridGrupy.DataBind();
Try it and tell say that works ;)
For Your problem You should create dwo EDM class for each data source. And simple in DDL select event Your choose of DataContext depends from user choose in DDL.
Example :
protected void DDL_SelectedItem(object sender, EventArgs e)
{
TypeOfQueryData query = null;//you must know what type is data You query
if(this.dropListGrupy.SelectedValue==someItemSelect)
{
DataClasses1DataContext db = new DataClasses1DataContext();
//query to get data from source
query= from p in db.Dzieckos
where p.Grupy.Numer == Convert.ToInt32(this.dropListGrupy.SelectedValue)
orderby p.Nazwisko
select new { p.Imie, p.Nazwisko };
}
if(this.dropListGrupy.SelectedValue==otherItemSelect)
{
DataClasses2DataContext db = new DataClasses2DataContext();
query= from p in db.Dzieckos
where p.Grupy.Numer == Convert.ToInt32(this.dropListGrupy.SelectedValue)
orderby p.Nazwisko
select new { p.Imie, p.Nazwisko };
}
this.GridGrupy.DataSource = null;
this.GridGrupy.DataSource = DzieciGrupa;
// this.GridView1.DataSourceID = String.Empty;//maybe You need do that
this.GridGrupy.DataBind();

ASP.net list of dropdownlists - similar to Access continuous form

What I'm looking for is a way to mimic the MS-Access style continuous form within asp.net. In one particular case, I want a control, bound to a datasource which returns a dropdownlist for each row, bound to the value within the datasource. Any change to any of the dropdownlists' would perform an update to the database instantly.
I have got halfway to achieving this using a repeater control, with the DropDownList.SelectedValue assigned within the Repeater.ItemDataBound event.
But now, supposing I add an OnSelectedIndexChanged event to the DropDownList - how would I then query the repeater to know which row I was on (to get the primary key value, for example)
I'm not sure this can be done easily.. so the question is what should I really be doing? I don't want to use a GridView that requires me to select a row to edit.. I just want to have the dropdownlists autopostback for any updates.
Hope that's clear?!
Cheers! :D
For examples sake, lets say we are binding to a custom class called Record
public class Record
{
public int Id;
public string Value;
}
If you put custom logic on the Repeater.OnItemCreated event you can attach the primary key to the id of the drop down list
protected void Repeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (!(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem))
return;
var dataItem = e.Item.DataItem as Record;
if (dataItem == null) return;
var dropdown = e.Item.FindControl("myDropDown") as DropDownList;
if (dropdown == null) return;
dropdown.ID = dropdown.ID + dataItem.Id;
}
Then on the SelectedIndexChange, you can pull the id off of the dropdown that fired the event.
protected void SelectedIndexChanged(object sender, EventArgs e)
{
var dropdown = sender as DropDownList;
if (dropdown == null) return;
var stringId = dropdown.ID.Replace("myDropDown", "");
int id;
if (Int32.TryParse(stringId, out id))
{
updateRecord(id, dropdown.SelectedValue);
}
}
It's very much an ugly hack, but it should allow you to do what you want.
Easiest way to tackle this would be to mimic the Access continuous form ASP.NET style. Which would be to make a UserControl to handle the row-level UI, then put said UserControl in a repeater.

Resources