Cannot get rid of duplicate values in populated listbox - c#

I have tried to look at other solutions, but I cannot seem to find the answer. I am currently using a listbox to show data from the database using a sqldatasource. It is populated after I select a value from a dropdownlist before hand. When using the listbox I want to save the selected items after I click it so I set AppendDataBoundItems to true. It seems when I set it to false, I no longer get duplicates values, however then I cannot keep the selected value of the listbox after binding. I have also tried to enable/disable the view state but no luck. I am positive that I am using the DISTINCT keyword in my query but still no luck.
ASP.Net
<asp:DropDownList ID="ProgramDropDownList" runat="server" AutoPostBack="True" DataSourceID="SqlDataSource1" DataTextField="Program" DataValueField="ProgramID">
</asp:DropDownList>
<asp:DropDownList ID="ReportPeriodDropDownList" runat="server" AutoPostBack="True" DataSourceID="SqlDataSource2" DataTextField="ReportLabel" DataValueField="DataCollectionPeriodID" Height="21px" Width="172px">
</asp:DropDownList>
<div style="width:400px; height:auto; overflow:auto; text-align: center; margin-left: auto; margin-right: auto; left: 0; right: 0">
<asp:ListBox ID="FormSectionListBox" DataSourceID="FormSectionDataSource" runat="server" AutoPostBack="True" DataTextField="FormSection" DataValueField="FormSectionID" AppendDataBoundItems="True" EnableViewState="False">
</asp:ListBox>
</div>
<asp:SqlDataSource ID="FormSectionDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:SmartFormConnection %>" SelectCommand="SELECT DISTINCT FormSection, FormSectionID FROM Core.FormSection_Lkup
where formsectionid IN (select formsectionid from core.form_section_subsection_item_rel where datacollectionperiodid = #datacollectionperiodid) order by FormSection">
<SelectParameters>
<asp:ControlParameter ControlID="ReportPeriodDropDownList" Name="datacollectionperiodid" PropertyName="SelectedValue" DefaultValue="" />
</SelectParameters>
</asp:SqlDataSource>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
_connection = DataAccess.SelfRef().GetConnection();
string eTarget = Request.Params["__EVENTTARGET"];
if (string.IsNullOrEmpty(eTarget)) return;
var list = InstructionDropDown.SelectedValue;
switch (list)
{
case "Form Section":
FormSectionListBox.DataSourceID = "FormSectionDataSource";
FormSectionListView.DataBind();
RenderView(FormSectionListView, "hidden"); // hide listview on page load
break;
}
}

I guess that you just have to ensure that the list is not filled on every postback:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
// do what you need on the initial load
}
}
If you need to handle the DropDownList selection use the appropriate events. In this case the SelectedIndexChanged event.
protected void InstructionDropDown_SelectedIndexChanged(Object sender, EventArgs e)
{
var list = InstructionDropDown.SelectedValue;
switch (list)
{
case "Form Section":
FormSectionListBox.DataSourceID = "FormSectionDataSource";
FormSectionListView.DataBind();
RenderView(FormSectionListView, "hidden"); // hide listview on page load
break;
}
}
}

I was able to find a work around. I set the AppendDataBoundItems to false. And used the SelectedIndexChanged Property to save the selected index after Binding.
protected void FormSectionListBoxSelectedIndexChanged(object sender, EventArgs e)
{
var item = FormSectionListBox.SelectedIndex;
FormSectionListBox.DataSourceID = "FormSectionDataSource";
FormSectionListView.DataBind();
FormSectionListBox.SelectedIndex = item;
}

Related

Can't set dropdown list selected item

I have a DropDown list on an ASP.Net web page. I'm trying to set its SelectedValue` on page load. I'm using this page as a reference. Here's my code:
<asp:DropDownList runat="server" ID="ddlType" DataSourceID="sdsType" DataTextField="Name" DataValueField="AssetTypeID" />
<asp:SqlDataSource runat="server" ID="sdsType" ConnectionString='<%$ ConnectionStrings:SystemManagement %>' SelectCommand="SELECT AssetTypeID, [Name] FROM AssetType UNION SELECT 0, '' ORDER BY [Name]" SelectCommandType="Text" />
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
if (Request.QueryString["searchtype"] != null)
{
ddlType.SelectedValue = ddlType.Items.FindByText(Request.QueryString["searchtype"]).Value;
ddlType.SelectedValue = "1";
}
}
else
{
}
}
The first line that sets the SelectedValue will give me a Null Reference Exception and if I inspect the ddlType it has no Items. However, if I comment out the first line setting the SelectedValue and set it using the second line (just hard coding the value) it works. What's going on?
You can use the OnDataBound event to do your current logic
/*Note the addition of "OnDataBound" */
<asp:DropDownList runat="server"
ID="ddlType"
DataSourceID="sdsType"
DataTextField="Name"
DataValueField="AssetTypeID"
OnDataBound="ddlType_DataBound"
/>
<asp:SqlDataSource runat="server" ID="sdsType" ConnectionString='<%$ ConnectionStrings:SystemManagement %>' SelectCommand="SELECT AssetTypeID, [Name] FROM AssetType UNION SELECT 0, '' ORDER BY [Name]" SelectCommandType="Text" />
protected void ddlType_DataBound(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
if (Request.QueryString["searchtype"] != null)
{
ddlType.SelectedValue = ddlType.Items.FindByText(Request.QueryString["searchtype"]).Value;
ddlType.SelectedValue = "1";
}
}
else
{
}
}
When you are trying to set the value for ddlType, the DataSource is not yet loaded to the DropDown. If you check the debugger, the ddlType.Items property will show you that it currently has no items, which explains the NullReference exception.
Try to call ddlType.DataBind() before to ensure that ddlType.Items has the items from the database.
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
ddlType.DataBind(); // Load data from DataSource
if (Request.QueryString["searchtype"] != null)
{
ddlType.SelectedValue = ddlType.Items.FindByText(Request.QueryString["searchtype"]).Value;
ddlType.SelectedValue = "1";
}
}
else
{
}
}
Make sure to have the ddlType.DataBind() inside the if(!Page.IsPostBack) condition, to avoid loading the data from the database on every PostBack.

Listview Update not workng

I'm trying to change the Select Command my DataSource uses using a dropdownlist. When the page loads it sets the select command depending on the selected index. When I change the dropdownlist the page refreshes but the data doesn't! Where am I going wrong?
.aspx file
<asp:DropDownList ID="filmFilter" runat="server" OnSelectedIndexChanged="filmFilter_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem Value="">Filter</asp:ListItem>
<asp:ListItem Value="priceASC">Price: Low-High</asp:ListItem>
<asp:ListItem Value="priceDSC">Price: High-Low</asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionStringFilms %>"></asp:SqlDataSource>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="filmID" DataSourceID="SqlDataSource1" OnSelectedIndexChanged="ListView1_SelectedIndexChanged">
<ItemTemplate>
...
</ItemTemplate>
<LayoutTemplate>
...
</LayoutTemplate>
</asp:ListView>
code-behind - page load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (filmFilter.SelectedIndex == 0)
{
SqlDataSource1.SelectCommand = "SELECT * FROM [films]";
}
if (filmFilter.SelectedIndex == 1)
{
SqlDataSource1.SelectCommand = "SELECT * FROM [films] ORDER BY [filmPrice]";
}
if (filmFilter.SelectedIndex == 2)
{
SqlDataSource1.SelectCommand = "SELECT * FROM [films] ORDER BY [filmPrice] DESC";
}
}
}
Thanks!
You've got it so your datasource is set on the page_load which is fine but you've wrapped it in
if (!IsPostBack)
{
Which means your code to change the datasource will only happen when you are not in postback (when you change the value of the dropdown you will be in a postback)
Have a read through
http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
It will help with your understanding

ASP.NET Get value from DropDownList in EditItemTemplate in codebehind

I have a GridView that I have placed in DropDownList's in 2 columns.
<asp:TemplateField HeaderText="Upgrade" SortExpression="Upgrade">
<ItemTemplate>
<asp:Label ID="LabelUpgrade" runat="server" Text='<%# Eval("Upgrade") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlUpgrade" runat="server" Width="100px">
<asp:ListItem Value="1">--Select--</asp:ListItem>
<asp:ListItem Value="2">1</asp:ListItem>
<asp:ListItem Value="3">2</asp:ListItem>
<asp:ListItem Value="4">3</asp:ListItem>
<asp:ListItem Value="5">4</asp:ListItem>
<asp:ListItem Value="6">5</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
how do I grab the item from ddlUpgrade in the codebehind?
OnUpdating Event - I don't have a way to pull the row to get the value from the drop down but I add my sql parameters here.
protected void IAP_Updating(object sender, SqlDataSourceCommandEventArgs e){}
RowUpdating Event - I can get the row here but I can't add the value to the sql parameters because e.command isn't valid here
protected void gvClients_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow _row = gvClients.Rows[e.RowIndex];
DropDownList _ddl = (DropDownList)_row.FindControl("ddlUpgrade");
SqlParameter _parm = new SqlParameter("#Upgrade", _ddl.SelectedItem.ToString());
}
On the RowUpdating event you can capture the control inside the edit template based on its ID.
GridViewRow row = GridView1.Rows[e.RowIndex];
DropDownList ddl = (DropDownList)row.FindControl("ddlUpgrade");
SqlParameter _parm = new SqlParameter("#Upgrade", ddl.SelectedItem.ToString());
e.Command.Parameters.Add(_parm);
I would add a hidden field outside the GridView:
<asp:HiddenField ID="hdnSelection" value="" runat="server" />
And change the gvClients_RowUpdating method:
protected void gvClients_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow _row = gvClients.Rows[e.RowIndex];
DropDownList _ddl = _row.FindControl("ddlUpgrade") as DropDownList;
if(_ddl != null)
{
hdnSelection.Value = _ddl.SelectedItem.Text;
IAP.Update();//Assuming IAP is the ID of the SqlDataSource
}
}
And my IAP_Updating method should look like this:
protected void IAP_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
SqlParameter _parm = new SqlParameter("#Upgrade", hdnSelection.Value);
e.Command.Parameters.Add(_parm);
}
I did not test the code. You may need to tweak.

How to get the previous item on DropDownList before OnSelectedIndexChanged fires the event

How would I get the previous item on DropDownList before OnSelectedIndexChanged fires the event?
Example: I had a DropDownList that has names as its items ("John", "Mark"). By default the SelectedIndex is "John". Upon changing its index and selecting "Mark" the event OnSelectedIndexChanged will be triggered. When I use ddlName.SelectedIndex it will return only the index for "Mark" which I want to get is the index of "John".
You can't capture an event prior to the change, but you could easily store the previous value in a variable. Each time SelectedIndexChanged is fired, use the previous value and then set it to the new index (for the next time the event fires). To handle the case when it's a new selection (from the default), you can either set the variable when the page loads, or allow it to be null and have that alert you to the fact it's a new selection (which you can then handle however you like).
<asp:DropDownList ID="ddlName" runat="server" AutoPostBack="true"
onselectedindexchanged="ddlName_SelectedIndexChanged">
<asp:ListItem Text="John" Value="1"></asp:ListItem>
<asp:ListItem Text="Mark" Value="2"></asp:ListItem>
<asp:ListItem Text="Jim" Value="3"></asp:ListItem>
</asp:DropDownList>
.cs file code here:
public static int PreviousIndex;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ddlName.AppendDataBoundItems = true;
ddlName.Items.Add(new ListItem("Other", "4"));
PreviousIndex = ddlName.SelectedIndex;
}
}
protected void ddlName_SelectedIndexChanged(object sender, EventArgs e)
{
string GetPreviousValue = ddlName.Items[PreviousIndex].Text;
Response.Write("This is Previously Selected Value"+ GetPreviousValue);
//Do selected change event here.
PreviousIndex = ddlName.SelectedIndex;
}
You could use the e.OldValues property.
<asp:DropDownList ID="esDropDownList" runat="server" DataSourceID="SqlDataSourceddlEnrolmentStatus" DataTextField="EnrolmentStatusDescription" DataValueField="EnrolmentStatusID" SelectedValue='<%# Bind("StudentEnrolmentStatus") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSourceddlEnrolmentStatus" runat="server"
ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>" SelectCommand="SELECT [EnrolmentStatusID], [EnrolmentStatusDescription] FROM [tblEnrolmentStatuses] ORDER BY [EnrolmentStatusID]">
</asp:SqlDataSource>
And in code behind (assuming your dropdownlist is in a formview) ...
protected void FormView1_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
{
..
String msg = "This is the new value " + e.NewValues["StudentEnrolmentStatus"].ToString()+ " and this is the old value " + e.OldValues["StudentEnrolmentStatus"].ToString();
..
}

Rebinding on Postback Based on Selected DropDown Value

Greetings!
I have a DropDownList within a FormView which are bound to XmlDataSources:
<asp:FormView ID="MyFormView" runat="server" DataSourceID="MyXmlDataSource">
<ItemTemplate>
<h1><%# XPath("SomeNode")%></h1>
<asp:Label ID="MyLabel" runat="server" AssociatedControlID="MyDdl" Text='<%# XPath("SomeOtherNode")%>' />
<asp:DropDownList ID="MyDdl"
runat="server"
DataSourceID="MyDdlDataSource"
DataTextField="name"
DataValueField="value"
AutoPostBack="true"
OnSelectedIndexChanged="MyDdl_SelectedIndexChanged">
</asp:DropDownList>
</ItemTemplate>
</asp:FormView>
<asp:XmlDataSource ID="MyXmlDataSource" runat="server" XPath="Root/MainSection" />
<asp:XmlDataSource ID="MyDdlDataSource" runat="server" XPath="Root/MainSection/Areas/*" />
In the page's codebehind, I have the following OnLoad() method as well as the method for when the select index of the dropdownlist changes:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
string xml = GetMyXml(0); // default value
MyXmlDataSource.Data = xml;
MyDdlDataSource.Data = xml;
}
}
protected void MyDdl_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList l_MyDdl = FindControl("MyDdl") as DropDownList;
int myVal;
if (l_MyDdl != null)
if (!Int32.TryParse(l_MyDdl.SelectedItem.Value, out myVal))
myVal = 0;
string xml = GetMyXml(myVal);
MyXmlDataSource.Data = xml;
MyDdlDataSource.Data = xml;
}
When a different value is selected from the dropdown list and SelectedIndexChanged is invoked, I am unable to get the value of the dropdown list (FindControl always returns null) in order to use it to re-bind the datasources. How can I get this value?
Because your dropdownlist is contained within another control it may be that you need a recursive findcontrol.
http://weblogs.asp.net/palermo4/archive/2007/04/13/recursive-findcontrol-t.aspx

Categories