I have a page with a gridview on it and a dropdown list which controls how many items per page the gridview will display.
The pageSize value of the gridview is controlled by this dropdown list and it gets saved to a cookie.
When the user loads the site the cookie is read so that it remembers what page size the user picked.
I have one problem and that is, if I pick another value on the dropdown list it does not update either cookie or dropdown list. It reverts back to the saved value.
This is the dropdown list created in the gridview pager template:
<PagerTemplate>
<asp:Table ID="Table3" runat="server" Width="100%">
<asp:TableRow>
<asp:TableCell HorizontalAlign="Left">
<asp:PlaceHolder ID="ph" runat="server"></asp:PlaceHolder>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Right" Width="10%">
Page Size
<asp:DropDownList runat="server" ID="ddlPageSize" AutoPostBack="true"
OnSelectedIndexChanged="ddlPageSize_SelectedIndexChanged" OnLoad="ddlPageSize_Load">
<asp:ListItem>5</asp:ListItem>
<asp:ListItem>10</asp:ListItem>
<asp:ListItem>20</asp:ListItem>
<asp:ListItem>50</asp:ListItem>
<asp:ListItem>100</asp:ListItem>
</asp:DropDownList>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</PagerTemplate>
and this is where I try to load the value of the dropdown list from cookie:
protected void Page_Load(object sender, EventArgs e)
{
string pageSize = "10";
//Try and load the PageSize cookie from the user's machine and default to 10 records if none is found.
if (Request.Cookies["PageSize"] != null)
{
if (Request.Cookies["PageSize"]["Value"] != null)
{
pageSize = Request.Cookies["PageSize"]["Value"];
int _pageSize;
int.TryParse(pageSize, out _pageSize);
gvRecordsList.PageSize = _pageSize;
DropDownList ddlPageSize = (gvRecordsList.BottomPagerRow).FindControl("ddlPageSize") as DropDownList;
ddlPageSize.SelectedIndex = ddlPageSize.Items.IndexOf(new ListItem(pageSize));
}
}
else
gvRecordsList.PageSize = 10;
if (IsPostBack)
{
ApplyPaging();
}
else
{
gvRecordsList.DataSourceID = "RecordsListSqlDataSource";
gvRecordsList.DataBind();
}
}
The dropdown list index changed code:
protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlPageSize = (gvRecordsList.BottomPagerRow).FindControl("ddlPageSize") as DropDownList;
gvRecordsList.PageSize = int.Parse(ddlPageSize.SelectedValue);
Response.Cookies["PageSize"]["Value"] = ddlPageSize.SelectedValue;
Response.Cookies["PageSize"].Expires = DateTime.Now.AddDays(1d);
}
When I step through the code of the SelectedIndexChanged method, I can see that ddlPageSize.SelectedValue always contains the value from the cookie, 50, even though I select another value.
I guess the question is, where do I set the index of the dropdown list?
DropDownList ddlPageSize = (gvRecordsList.BottomPagerRow).FindControl("ddlPageSize") as DropDownList;
ddlPageSize.SelectedIndex = ddlPageSize.Items.IndexOf(new ListItem(pageSize));
The Page_Load event executes before the DropDownList SelectedIndexChanged event. And you are loading the cookie's value to the DropDownList on the PageLoad event.
I suggest you to try loading the cookie afterwards, on the OnPreRender event for example.
Or add a condition to your Page_Load logic, verifying if the PostBack is caused by the DropDownList:
DropDownList ddlPageSize = (gvRecordsList.BottomPagerRow).FindControl("ddlPageSize") as DropDownList;
bool isDDLPostingBack = Request["__EVENTTARGET"] == ddlPageSize.UniqueID;
if (Request.Cookies["PageSize"]["Value"] != null && !isDDLPostingBack)
{
...
}
Related
I have a problem with dropdown list.
When I select one value in dropdown and I click on submmit button, after that, selected value is disappearing. But, I reload this page, selected value is appearing. I don't the reload page - I use PostBack.
.aspx page:
<asp:DropDownList ID="ddl1" runat="server" Height="18px" Width="172px" AutoPostBack="true" DataTextField="Name1" DataValueField="Value1" OnSelectedIndexChanged="ddl1_SelectedIndexChanged" TabIndex="5" >
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
dt = np.GetData();
ddl1.DataSource = np.GetData(); //stored procedure
ddl1.DataTextField = "Name1";
ddl1.DataValueField = "Value1";
ddl1.DataBind();
ddl1.Items.Insert(0, "");
ddl1.EnableViewState = true;
}
I am using 3 DropDownList inside DataList. So, each row contains 3 DropDownList. DataList also contains DataKeyField.
Now, if user select value from DropDownList1 then I want to bind DropDownList2 and if user select value from DropDownList2 then I want to bind DropDownList3. I am using SelectedIndexChanged and I am able to get value of related DropDownList selected value. But, If user select DropDownList2 then I also need value of DropDownList1 and also need value of respected DataKeyField.
How to get this ???
My code Sample:
<asp:DataList ID="dlTest" runat="server" OnItemDataBound="dlTest_ItemDataBound"
DataKeyField="TestId">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"> </asp:DropDownList>
<asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList2_SelectedIndexChanged"> </asp:DropDownList>
<asp:DropDownList ID="DropDownList3" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList3_SelectedIndexChanged"> </asp:DropDownList>
</ItemTemplate>
</asp:DataList>
Here, onSelectedIndexChanged of DropDownList3, I am able to get selectedValue of it but I also need respected row's selectedValue of DropDownList1 and DropDownList2 and also respected DataKeyField value.
protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
{
var DropDownList3 = (DropDownList)sender;
string DDL3 = ((DropDownList)DropDownList3.NamingContainer.FindControl("DropDownList3")).SelectedValue;
// Also need selectedValue of DropDownList1 and DropDownList2 and DataKeyField.
}
I think you are almost there. You just need to. Using your code:
protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
{
var DropDownList1 = (DropDownList)sender;
var DropDownList2 = (DropDownList)sender;
var DropDownList3 = (DropDownList)sender;
string DDL1 = ((DropDownList)DropDownList1.NamingContainer.FindControl("DropDownList1")).SelectedValue;
string DDL2 = ((DropDownList)DropDownList2.NamingContainer.FindControl("DropDownList2")).SelectedValue;
string DDL3 = ((DropDownList)DropDownList3.NamingContainer.FindControl("DropDownList3")).SelectedValue;
}
Either way I would do it a little bit different:
item valueddl1 = DropDownList1.SelectedValue;
And so on; which should work as weel and it is a little bit more simple.
I have an edit button and a dropdownlist inside a formview. I am using Linq To Entities to get the data I need to work with and have no problem populating and viewing the formview itemtemplate.
However, the dropdownlist control (id="ddlEligibility") is only in theedititemtemplate (I use a textbox in the itemtemplate to display the current value) and I am having a problem getting the value initially shown in the itemtemplate to appear when the edititemtemplate is shown. All I get right now is the dropdownlist with the first value shown. I want the value from the itemtemplate to appear by default and the user can change it if they wish. Here is the code that populates the dropdownlist. Anyone have a suggestions?
protected void btnEdit_Click(object sender, EventArgs e)
{
fvSubscriber.ChangeMode(FormViewMode.Edit);
fvSubscriber.DataBind();
LifeLineDSEntities context = new LifeLineDSEntities():
var program = from p in context.EligibilityPrograms
select p;
DropDownList ddlEligibility = (DropDownList)(fvSubscriber.FindControl("ddlEligibility")));
if (ddlEligibility != null)
{
ddlEligibility.DataSource = program;
ddlEligibility.DataTextField = "ProgramName";
ddlEligibility.DataValueField = "eligibilityCode";
ddlEligibility.DataBind();
}
}
DropDownlist in FormView...
<form id="form1" runat="server">
<asp:FormView ID="fvSubscriber" runat="server" RenderOuterTable="false" DefaultMode="Readonly" OnModeChanging="fvSubscriberChanging">
<ItemTemplate>
<asp:TextBox ID="txtEligibility" runat="server" Text='<%# Eval("ProgramName") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlEligibility" runat="server" />
</EditItemTemplate>
</asp:FormView>
</form>
You could try getting the value of the textbox before you change the formview mode.
TextBox txtEligibility= (TextBox)fvSubscriber.FindControl("txtEligibility");
fvSubscriber.ChangeMode(FormViewMode.Edit);
fvSubscriber.DataBind();
LifeLineDSEntities context = new LifeLineDSEntities():
var program = from p in context.EligibilityPrograms
select p;
DropDownList ddlEligibility = (DropDownList)(fvSubscriber.FindControl("ddlEligibility")));
if (ddlEligibility != null)
{
ddlEligibility.DataSource = program;
ddlEligibility.DataTextField = "ProgramName";
ddlEligibility.DataValueField = "eligibilityCode";
ddlEligibility.DataBind();
if (txtEligibility != null)
{
if(!string.IsNullOrWhiteSpace(txtEligibility.Text))
{
foreach (ListItem item in ddlEligibility.Items)
{
if (item.Text == txtEligibility.Text)
{
ddlEligibility.SelectedValue = txtEligibility.Text;
}
}
}
}
}
I am using a LinqDataSource and a FormView with paging enabled on an ASP.NET page. I am trying to access the FormView's DataItem property on PageLoad and I have no trouble on the first page load, but as soon as I use the Next/Prev page button (causing a postback) on the FormView the DataItem property is null, even if there a record showing in the FormView. Any ideas why it works fine on the first page load but not on a postback?
If you're curious what my PageLoad event looks like, here it is:
protected void Page_Load(object sender, EventArgs e)
{
Label lbl = (Label)fvData.FindControl("AREALabel");
if (fvData.DataItem != null && lbl != null)
{
INSTRUMENT_LOOP_DESCRIPTION record = (INSTRUMENT_LOOP_DESCRIPTION)fvData.DataItem;
var area = db.AREAs.SingleOrDefault(q => q.AREA1 == record.AREA);
if (area != null)
lbl.Text = area.AREA_NAME;
}
}
The object you bind to any data-bound control won't be persisted in the page's ViewState
Therefore, on subsequent posts the DataItem property will be null unless you re-bind the control
This property will contain a reference to the object when the control is bound.
Usually you would need to access this property if you want to do something when the objects is bound, so you need to react to the DataBound event
Example:
Output
Code behind
protected void ds_DataBound(object sender, EventArgs e)
{
var d = this.fv.DataItem as employee;
this.lbl.Text = d.lname;
}
ASPX
<asp:LinqDataSource ID="lds" runat="server"
ContextTypeName="DataClassesDataContext"
TableName="employees"
>
</asp:LinqDataSource>
<asp:FormView runat="server" ID="fv" DataSourceID="lds" AllowPaging="true"
OnDataBound="ds_DataBound">
<ItemTemplate>
<asp:TextBox Text='<%# Bind("fname") %>' runat="server" ID="txt" />
</ItemTemplate>
</asp:FormView>
<br />
<asp:Label ID="lbl" runat="server" />
Your data will not be preserved on PostBack. You'll need to rebind the FormView in the PageIndexChanging event using something like:
protected void FormView_PageIndexChanging(object sender, FormViewPageEventArgs e)
{
FormView.PageIndex = e.NewPageIndex;
//rebind your data here
}
On an ASP.NET page, I have a gridview which contains a dropdownlist in one of its columns. While other columns in the gridview are databound, the dropdown list is NOT, and only contains 3 preset values "Frank", "Yes", and "No". ("Frank" is used as an example so that I don't get false readings from my preferred blank option)
<asp:GridView ID="testGrid" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Code1" HeaderText="Code1" />
<asp:BoundField DataField="Code2" HeaderText="Code2" />
<asp:TemplateField HeaderText="Like Frank?">
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlLikeFrank">
<asp:ListItem>Frank</asp:ListItem>
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:HyperLinkField ... HeaderText="File" />
</Columns>
</asp:GridView>
<br />
<asp:Button ID="cmdUpdate" runat="server" Text="Update" OnClick="cmdUpdate_Click" /></div>
I don't need AutoPostBack on these dropdownlists, as I only want to consider their selected values when the button cmdUpdate is clicked.
protected void cmdUpdate_Click(object sender, EventArgs e)
{
bool likesFrank = false;
string selected = "";
DropDownList ddl = null;
GridViewRow current = null;
// Go through each row and check the dropdown list.
for (int i = 0; i < testGrid.Rows.Count; i++)
{
current = testGrid.Rows[i];
...
ddl = (DropDownList)(current.FindControl("ddlLikeFrank"));
/* THIS FOR LOOP IS WAS USED FOR INVESTIGATING THIS ISSUE*/
for (int j = 0; j < ddl.Items.Count; j++)
{
if (ddl.Items[j].Selected)
{
continue;
}
}
selected = ddl.SelectedItem.Value;
switch (selected)
{
case LIKE: // "Yes"
likesFrank = true;
break;
case DONT_LIKE: // "No"
likesFrank = false;
break;
default: // If nothing is selected in the drop-down list, move on.
continue;
} // end switch block
/* USE THE DERIVED BOOLS HERE */
} // end for loop on grid rows
} // end method cmdUpdateClick
The problem is this: No matter what item is selected in any of the dropdownlists, my page thinks that every single one of them is set to "Frank", i.e. the first item. Moreover, if I put a breakpoint on the top of the for loop denoted as the "Investigation code", and then interact with the page as follows:
Select different dropdownlist options for different rows.
Click the Update button.
... my debugging code tells me that none of the items are selected! Not one of them!! I can be looking at 2 Yes's and 3 No's on the page, and my debug tools in VS2008 are telling me that every single dropdownlist has nothing selected.
How can this be possible? (NOTE: I have tried this with EnableViewState set to true, and with EnableViewState not even mentioned in the page header.)
Thanks.
take a hit with this. Replace index based for with this
foreach(GridViewRow row in grid.Rows)
{
var ddlVal = ((DropDownList)row.FindControl("yourId")).SelectedItem.Value;
}
<< use SelectedItem.Value - I think this will solve your problem >>
Update:
To update the selected index of the ddl you needto do a postback. Enable autopostback=true. But here , you have mentioned you do not want autopostback, since this isthe only workaround, so place the gridview in an updatepanel to suppress postback
At server side
protected void btnSaveRankChanges_Click(object sender, EventArgs e)
{
foreach (GridViewRow grv in GridViewRankChanges.Rows)
{
DropDownList dropDownChangeRank = (DropDownList)grv.FindControl("DropDownListRank");
StudentInfoObject.RankID = Convert.ToInt32(dropDownChangeRank.SelectedValue);
}
}
in grid
<asp:TemplateField HeaderText="Select New Rank">
<ItemTemplate>
<asp:DropDownList ID="DropDownListRank" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
On button click
<asp:Button ID="btnSaveRankChanges" runat="server" Text="Submit" ValidationGroup="RankChanges"
class="accordionHeader" Height="27px" OnClick="btnSaveRankChanges_Click" OnClientClick="LoadImage()" />
Dropdown binds in this way
/// <summary>
/// bind dropdown with rank in grid
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void GridViewRankChanges_RowDataBound(object sender, GridViewRowEventArgs e)
{
DropDownList drdList;
// Nested DropDownList Control reference is passed to the DrdList object. This will allow you access the properties of dropdownlist placed inside the GridView Template column.
if (e.Row.RowType == DataControlRowType.DataRow)
{
//bind dropdown rank
drdList = (DropDownList)e.Row.FindControl("DropDownListRank");
drdList.DataSource = RankList.GetRankList(false);
drdList.DataTextField = "Rank";
drdList.DataValueField = "RankID";
drdList.DataBind();
drdList.Items.Insert(0, new ListItem("Select", "0"));
}
}
It works for me hope it helps for you too.
I think you are rebinding the grid on every post back, which will reload the entire data along with dropdowns. For ex. Please check if(!page.IsPostBack) before doing databiniding of gridview.
Please let me know if this is not the issue.