I have two bound to objectdatasource dropdownlists.
<asp:DropDownList ID="ddlProgram" runat="server" DataSourceID="ProgramsDS"
DataTextField="NAME" DataValueField="ID" AutoPostBack="True"
OnSelectedIndexChanged="ddlProgram_SelectedIndexChanged">
</asp:DropDownList>
<asp:ObjectDataSource ID="ProgramsDS" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetData"
TypeName="WebAdminTools.DATA.DSTableAdapters.ProgramTA"
UpdateMethod="Update">
</asp:ObjectDataSource>
<br/>
<asp:DropDownList runat="server" ID="ddlVersion" AutoPostBack="True"
OnSelectedIndexChanged="ddlVersion_SelectedIndexChanged" Width="158px"
DataSourceID="VersionDS" DataTextField="VERSION"
DataValueField="PROGRAM_ID"/>
<asp:ObjectDataSource ID="VersionDS" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetData"
TypeName="WebAdminTools.DATA.DSTableAdapters.UpdateTA">
<SelectParameters>
<asp:ControlParameter ControlID="ddlProgram" DefaultValue="0"
Name="P_ID" PropertyName="SelectedValue" Type="Int32"/>
</SelectParameters>
</asp:ObjectDataSource>
I have onSelectionIndexChanged event handler for the second dropdownlist as well. When I try to pick item from second dropdownlist it resets to first one. I tried this guide What am I doing wrong?
Edit:
protected void ddlVersion_SelectedIndexChanged(object sender, EventArgs e)
{
GetCompaniesForUpdate();
}
private void GetCompaniesForUpdate()
{
ProgramVersionTA ta = new ProgramVersionTA();
var dt = new DS.ProgramsVersionsDataTable();
ta.Fill(dt, Convert.ToInt32(ddlVersion.SelectedValue));
var selectedVersion = Version.Parse(ddlVersion.SelectedValue);
var companyForUpdate = dt.Where(c => Version.Parse(c.MAX_AVAILABLE_VERSION) > selectedVersion
&& Version.Parse(c.VERSION) < selectedVersion);
lbCompanies.DataSource = companyForUpdate;
lbCompanies.DataMember = "NAME";
lbCompanies.DataBind();
}
I think it is because of the postback. if u are setting a value to dropdownlist on form_load, please make sure that u put it inside the if(!Page.IsPostBack).
Related
I have what I hope is a simple question. I have a gridview control that's bound to a sqldatasource.
First, the relevant code:
<asp:DropDownList ID="cboCustomerID" runat="server"
DataSourceID="DataSourceCustomer" DataTextField="CustomerName" DataValueField="CustomerID">
</asp:DropDownList>
<asp:DropDownList ID="cboStaffID" runat="server"
DataSourceID="DataSourceStaff" DataTextField="StaffFullName" DataValueField="StaffID">
</asp:DropDownList>
<div><gcctl:MyCheckBox ID="chkShowClosed" Text="Show Closed Jobs?" Checked="false" AutoPostBack="true" runat="server" /></div>
<div><asp:Button ID="btnSearch" runat="server" OnClick="btnSearch_Click" Text="Search" /></div>
<div id="customersearchresults" class="searchresults">
<asp:SqlDataSource id="gvJobsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:GeekCommandConnString %>"
SelectCommand="SELECT j.JobID, j.JobName, s.JobStatus, jal.[JobAssignmentsFullList]
FROM (SELECT * FROM [dbo].[Jobs] WHERE ((NULLIF(#CustomerSearch,'') IS NOT NULL AND CustomerID = #CustomerSearch) OR (NULLIF(#CustomerSearch,'') IS NULL))) j
INNER JOIN (SELECT * FROM [list].[JobStatuses] WHERE ((#ShowClosed = 0 AND IsStatusOpen = 1) OR (#ShowClosed = 1)) AND IsActive = 1) s ON j.JobStatusID = s.JobStatusID
LEFT JOIN (SELECT * FROM [dbo].[JobAssignments] WHERE ((NULLIF(#StaffSearch,'') IS NOT NULL AND StaffID = #StaffSearch) OR (NULLIF(#StaffSearch,'') IS NULL))) ja ON j.JobID = ja.JobID
LEFT JOIN [dbo].[udv_JobAssignmentsCommaDelimited] jal ON j.JobID = jal.JobID
">
<SelectParameters>
<asp:Parameter Name="CustomerSearch" Type="Int32" />
<asp:Parameter Name="StaffSearch" Type="Int32" />
<asp:Parameter Name="ShowClosed" Type="Boolean" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="gvJobs" runat="server" AllowSorting="True"
AutoGenerateColumns="False"
DataKeyNames="JobID"
DataSourceID="gvJobsDataSource"
AutoGenerateDeleteButton="False"
AutoGenerateEditButton="False"
AutoGenerateSelectButton="False"
CssClass="searchresultsgrid"
AllowPaging="True" PageSize="50"
OnRowCommand="gvJobs_RowCommand"
EmptyDataText="No matching jobs on record." >
<Columns>
<asp:templatefield>
<itemtemplate>
<asp:linkbutton id="btnEdit" runat="server" CommandName="JobEdit" OnClientClick="PageForm.target ='_blank';" text="View/Edit" />
</itemtemplate>
</asp:templatefield>
<asp:BoundField DataField="JobID" HeaderText="ID" InsertVisible="false" ReadOnly="true" Visible="false" SortExpression="JobID" />
<asp:templateField HeaderText="Job Name" SortExpression="JobName">
<ItemTemplate><%# Eval("JobName") %></ItemTemplate>
</asp:templateField>
<asp:templateField HeaderText="Assigned to" SortExpression="JobAssignmentsFullList">
<ItemTemplate><%# Eval("JobAssignmentsFullList") %></ItemTemplate>
</asp:templateField>
</Columns>
</asp:GridView>
</div>
<asp:SqlDataSource ID="DataSourceCustomer" runat="server"
ConnectionString="<%$ ConnectionStrings:GeekCommandConnString %>"
SelectCommand="SELECT NULL AS [CustomerID]
, NULL AS [CustomerName]
UNION SELECT [CustomerID]
,[CustomerName]
FROM [GeekCommand].[dbo].[Customers]
WHERE ((#ShowInactive = 0 AND IsActive = 1) OR (#ShowInactive = 1))
ORDER BY CustomerName">
<SelectParameters>
<asp:ControlParameter Name="ShowInactive" Type="Boolean" ControlID="chkCustomersShowInactive" PropertyName="Checked" />
</SelectParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="DataSourceStaff" runat="server"
ConnectionString="<%$ ConnectionStrings:GeekCommandConnString %>"
SelectCommand="SELECT NULL AS [StaffID]
, NULL AS [StaffFullName]
UNION SELECT [StaffID]
,COALESCE([FirstName], [Nickname], '') + ' ' + COALESCE([LastName], '') AS StaffFullName
FROM [GeekCommand].[dbo].[Staff]
WHERE ((#ShowInactive = 0 AND IsActive = 1) OR (#ShowInactive = 1))
ORDER BY StaffFullName">
<SelectParameters>
<asp:ControlParameter Name="ShowInactive" Type="Boolean" ControlID="chkStaffShowInactive" PropertyName="Checked" />
</SelectParameters>
</asp:SqlDataSource>
And the relevant aspx.cs code:
int? iCustomerID;
int? iStaffID;
//--------
protected void SetIDs()
{
this.iCustomerID = null;
this.iStaffID = null;
if (Request.QueryString["customerid"] != null) //new customer
{
try
{
this.iCustomerID = Convert.ToInt32(Request.QueryString["customerid"]);
}
catch { }
}
if (Request.QueryString["staffid"] != null) //new customer
{
try
{
this.iStaffID = Convert.ToInt32(Request.QueryString["staffid"]);
}
catch { }
}
if (iCustomerID != null)
{
cboCustomerID.SelectedValue = iCustomerID.ToString();
}
if (iStaffID != null)
{
cboStaffID.SelectedValue = iStaffID.ToString();
}
}
//--------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetIDs();
}
}
//--------
protected void btnSearch_Click(object sender, EventArgs e)
{
gvJobsDataSource.SelectParameters["CustomerSearch"].DefaultValue = cboCustomerID.SelectedValue.ToString();
gvJobsDataSource.SelectParameters["StaffSearch"].DefaultValue = cboStaffID.SelectedValue.ToString();
gvJobsDataSource.SelectParameters["ShowClosed"].DefaultValue = chkShowClosed.Checked.ToString();
gvJobs.DataBind();
}
When I run the following in SSMS, I get 2 rows back, as I should:
DECLARE #CustomerSearch int, #StaffSearch int, #ShowClosed bit
SELECT #CustomerSearch = 2331, #StaffSearch = '', #ShowClosed = CAST(0 AS bit)
SELECT j.JobID, j.JobName, s.JobStatus, jal.[JobAssignmentsFullList]
FROM (SELECT * FROM [dbo].[Jobs] WHERE ((NULLIF(#CustomerSearch,'') IS NOT NULL AND CustomerID = #CustomerSearch) OR (NULLIF(#CustomerSearch,'') IS NULL))) j
INNER JOIN (SELECT * FROM [list].[JobStatuses] WHERE ((#ShowClosed = 0 AND IsStatusOpen = 1) OR (#ShowClosed = 1)) AND IsActive = 1) s ON j.JobStatusID = s.JobStatusID
LEFT JOIN (SELECT * FROM [dbo].[JobAssignments] WHERE ((NULLIF(#StaffSearch,'') IS NOT NULL AND StaffID = #StaffSearch) OR (NULLIF(#StaffSearch,'') IS NULL))) ja ON j.JobID = ja.JobID
LEFT JOIN [dbo].[udv_JobAssignmentsCommaDelimited] jal ON j.JobID = jal.JobID
But when I select a customer (specifically the customer whose id is 2331) in debug mode and step through the btnSearch_Click code, cboCustomerID.SelectedValue = "2331", cboStaffID.SelectedValue = "", chkShowClosed.Checked = false (all of which is correct)... but nothing happens when I step past the databind command. The gridview continues to show "No matching jobs on record."
I feel like I'm missing something really obvious, but I can't for the life of me figure out what it is.
UPDATE: Ok. This is interesting. Apparently, the query never gets sent to the SQL Server. I just started up SQL Server in trace mode, reloaded the aspx page, and did a search, and while the queries that are behind the two dropdownlists are there in the log, the query that's behind the gridview is just not there.
UPDATE #2: I've replaced the select parameters with the following:
<asp:ControlParameter Name="CustomerSearch" ControlID="cboCustomerID" PropertyName ="SelectedValue" />
<asp:ControlParameter Name="StaffSearch" ControlID="cboStaffID" PropertyName ="SelectedValue" />
<asp:ControlParameter Name="ShowClosed" Type="Boolean" ControlID="chkShowClosed" PropertyName="Checked" />
...and removed the extra code in the btnSearch_Click event, so the only line in that code is:
protected void btnSearch_Click(object sender, EventArgs e)
{
gvJobs.DataBind();
}
...no change. Still nothing happens when I click the search button.
Yay! Found the answer:
https://forums.asp.net/t/1243253.aspx?Gridview+Databind+Not+Working
The issue was that the gridviews have a property: CancelSelectOnNullParameter, which is true by default. Since at least one of the drop down lists is almost always null when I do the search, this resulted in nothing happening when I hit the search button. When I added CancelSelectOnNullParameter="false" to the gridview control, it fixed the problem.
(Semi-related note) I also added the following to the ControlParameters: ConvertEmptyStringToNull="true"
Thanks to the very helpful answers I have been able to modify my page so my dropdown boxes correctly update with the selected results from my SQL query.
The last phase of my testing is to update the changed record into the database. Regardless of what I do, I keep getting an error - Input string was not in a correct format.
It looks like the text value is being passed instead of the Author's ID - but I have identified the AuthorID in the datavaluefield. Below is my code:
protected void btnAddAuthors(object sender, EventArgs e)
{
odsIdentifiedAuthors.Insert();
lbAuthors.ClearSelection();
Response.Redirect(Request.Url.AbsoluteUri);
}
protected void groupList_TextSelected(object sender, EventArgs e)
{
lbUserList.Items.Clear();
lbUserList.Items.Add(new ListItem(DropDownList1.SelectedItem.Text, DropDownList1.SelectedItem.Text));
lbUserList.Items.FindByValue(DropDownList1.SelectedItem.Text).Selected = true;
}
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="True"
DataSourceID="SqlDataSource2" DataTextField="Author_Name" EnableViewState="false"
DataValueField="ID" OnSelectedIndexChanged="AuthorsList_TextSelected" AutoPostBack="true">
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:Libros %>"
SelectCommand="SELECT [Author_Name], [AuthorID] FROM [Authors] WHERE ([Genre] = #Genre)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlAuthors" Name="Genre"
PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
How do I resolve this error?
The ControlParameter's ControlID attribute refers to the ID of the DropDownList's, so the two have to match:
<asp:DropDownList ID="ddlAuthors" ...
//DataValueField have set as ID. But it should be "AuthorID"
Add this
DataValueField="AuthorID"
so I am running a C# function in that is supposed to change the colors of the text based on the value. When I removed the function from the list view it would output the values but when I included it, it would output nothing I have now finally figured out that there is nothing wrong with my function but with how i am binding my data to my list view, so I am wondering what is it I am doing wrong.
Here is my code:
<asp:SqlDataSource id="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:2007 SoundAssist VER 1.0.5 05-12-2011 (2013-06-24)ConnectionString %>" ProviderName="<%$ ConnectionStrings:2007 SoundAssist VER 1.0.5 05-12-2011 2013-06-24)ConnectionString.ProviderName %>" SelectCommand="SELECT [Plant], [Group No#] AS column1, [Group], [Job Code] AS Job_Code, [TWA], [Job Classification] AS Job_Classification, [Job Function] AS Job_Function, [Job Description] AS Job_Description FROM [Temp Table that contains TWA values] WHERE (([Job Description] = ?) AND ([Group] = ?) AND ([Job Classification] = ?))">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList6" Name="Job_Description" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="DropDownList4" Name="Group" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="DropDownList5" Name="Job_Classification" PropertyName="SelectedValue" Type="String" />
</SelectParameters>
and my list view line:
<asp:ListView id="YourListView" runat="server" DataSourceID="SqlDataSource3" OnItemDataBound="YourListView_ItemDataBound" >
And my color function:
protected void YourListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Label theTWALabel = (Label)e.Item.FindControl("TWALabel");
int theTWAValue = Convert.ToInt32(theTWALabel.Text);
if (theTWAValue >= 85)
{
if (theTWAValue < 90)
{
theTWALabel.CssClass = "YellowThis";
}
else
{
theTWALabel.CssClass = "RedThis";
}
}
}
}
And here is the List View:
<ItemTemplate>
<span style="background-color: white;color: #333333; border: 2em; border-width:1em; border-color:black;">
Plant Name:
<asp:Label id="PlantLabel" runat="server" Text='<%# Eval("Plant") %>' />
<br />
Department #:
<asp:Label id="column1Label" runat="server" Text='<%# Eval("column1") %>' />
<br />
Department Name:
<asp:Label id="GroupLabel" runat="server" Text='<%# Eval("Group") %>' />
<br />
Job Code:
<asp:Label id="Job_CodeLabel" runat="server" Text='<%# Eval("Job_Code") %>' />
<br />
TWA
<asp:Label id="TWALabel" runat="server" Text='<%# Eval("TWA") %>' />
<br />
</span>
</ItemTemplate>
Also I didn't type these in (The Sql statement I mean), I used the built in asp.net connection wizard to do this, and it created it all for me.
Edit: If there is any other info you need to help answer this question, please comment
Edit2: Is it possible that I need a if post back function?
The problem is that you are trying to access the controls in the YourListView_ItemDataBound event handler, and at that point the ListView doesn't have loaded yet.
Try adding to your ListView the event handler onLoad and inside that method then you work with your items like:
protected void YourListView_Load(object sender, EventArgs e)
{
Label theTWALabel;
int theTWAValue;
foreach (ListViewItem item in YourListView.Items)
{
theTWALabel = (Label)item.FindControl("TWALabel");
theTWAValue = Convert.ToInt32(theTWALabel.Text);
if (theTWAValue >= 85)
{
if (theTWAValue < 90)
theTWALabel.ForeColor = System.Drawing.Color.Yellow;
else
theTWALabel.ForeColor = System.Drawing.Color.Red;
}
}
}
You could try to loop through the controls rather than using FindControl.
if (e.Item.ItemType == ListViewItemType.DataItem)
{
foreach (Control c in e.Item.Controls)
{
if (c is Label && c.ID.Contains("TWALabel"))
{
Label theTWALabel = (Label)c
int theTWAValue = Convert.ToInt32(theTWALabel.Text);
if (theTWAValue >= 85)
{
if (theTWAValue < 90)
{
theTWALabel.CssClass = "YellowThis";
}
else
{
theTWALabel.CssClass = "RedThis";
}
}
}
}
}
Even if .Net modifies the ID name, you can check to see if the ID has the substring TWALabel and find your control that.
There is probably a better way to do it, but I can't think of another way that I know will work.
The YourListView_ItemDataBound method is called as the List view is being data bound. This is at the point where asp.net is creating a row in your grid for each row in your data source, so you will not be able to access the posted back data by pulling it from the control like you are doing. It is too late, as that old version of the grid has already been discarded.
I think you can either
Have the TWALabel autopostback to the server and create an OnChange event.
Parse the Request.Params to find the posted back value for each row
Try and pull what you need earlier in the page lifecycle before the databinding occurs. I think you would still have access to this data during Page_Load
I have an ObjectDataSource
<asp:ObjectDataSource SelectCountMethod="GetCount" EnablePaging="true" SortParameterName="sortExpression" ID="customersDS" runat="server" SelectMethod="GetList" TypeName="expenses.Classes.ExpenseFactory" DeleteMethod="Delete" UpdateMethod="Update" >
<SelectParameters>
<asp:ControlParameter ControlID="IdHidden" PropertyName="Value" Name="userId" />
<asp:Parameter DbType='Boolean' DefaultValue='false' Name='isExpense' />
<asp:Parameter DbType='Boolean' DefaultValue='false' Name='containRepeated' />
<asp:ControlParameter DbType="Int32" DefaultValue="" ControlID="CategorySelector2" Name="categoryId" />
<asp:ControlParameter DbType="DateTime" DefaultValue="" ControlID="FromSpentDateCalendarBox" Name="from" />
<asp:ControlParameter DbType="DateTime" DefaultValue="" ControlID="ToSpentDateCalendarBox" Name="to" />
</SelectParameters>
<UpdateParameters>
<asp:ControlParameter ControlID="IdHidden" PropertyName="Value" Name="userId" />
<asp:Parameter DbType='Boolean' DefaultValue='false' Name='isExpense' />
</UpdateParameters>
</asp:ObjectDataSource>
connected to a GridView
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
AllowPaging="True" AllowSorting="True"
DataSourceID="customersDS" CssClass="gtable sortable width100" DataKeyNames="Id"
AlternatingRowStyle-CssClass="odd" CellPadding="0" GridLines="None" OnPreRender="PreRender"
OnRowDataBound="GridView1_RowDataBound"
>
with edit and delete buttons in a CommandField
<asp:CommandField ItemStyle-Width="75px" HeaderStyle-Font-Bold=true HeaderText="<%$ Resources:Default, Actions %>" EditImageUrl="~/img/edit.png" ButtonType='Image' ShowEditButton="True" UpdateImageUrl="~/img/save.gif" CancelImageUrl="~/img/cancel.png" >
<ControlStyle CssClass="my_edit_buttons" />
</asp:CommandField>
Everything is located inside and UpdatePanel. The GridView and ObjectDataSource support and use paging. Paging works without any problems. The problem is editing. When I click edit on the first page, everything works as expected. When I click edit on the n-th item on the second or other page (greater than one), the GridView switches to the first page and selected the n-th item for editing.
(More concerete example: I switch to the second page, I select the item number 2 on that page to be edited, the GridView switches to the first page and selects the item number 2 (on the first page) to be edited).
Any ideas what may be the problem?
EDIT:
PreRender (setting GridView header):
protected void PreRender(object sender, EventArgs e)
{
try
{
GridView1.UseAccessibleHeader = false;
GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;
}
catch
{
}
}
RowDataBound (changind delete button to a custom one with configmation prompt|:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// we are using a html anchor and a hidden asp:button for the delete
HtmlAnchor linkDelete = (HtmlAnchor) e.Row.FindControl("linkDelete");
ImageButton btnDelete = (ImageButton) e.Row.FindControl("btnDelete");
string prompt = Resources.Default.DeletePrompt;
linkDelete.Attributes["onclick"] = string.Format(prompt, btnDelete.ClientID);
Expense expense = e.Row.DataItem as Expense;
if (expense!=null)
{
if (expense.SpentDate>DateTime.Now)
{
e.Row.CssClass = "future";
}
}
e.Row.Cells[1].CssClass = e.Row.Cells[4].CssClass = "red";
}
When I select a value from the dropdownlist, I like that value to be save in the #TimeZone value that is needed for
InsertCommand="INSERT INTO [Companies] ([TimeZone]) VALUES ( #TimeZone)"
I am not sure how to do this.
Here is my code:
Within my page load, I have the following code that assigns value to the drop down:
ddlTimeZone.DataSource = from p in TimeZoneInfo.GetZones()
select new { p.Id };
ddlTimeZone.DataTextField = "Id";
ddlTimeZone.DataValueField = "Id";
ddlTimeZone.DataBind();
Next, within my .aspx file, I have the following:
<EditItemTemplate>
<asp:DropDownList ID="ddlTimeZone" runat="server">
</asp:DropDownList>
</EditItemTemplate>
..... .....
InsertCommand="INSERT INTO [Companies] ([TimeZone]) VALUES ( #TimeZone)"
<InsertParameters>
<asp:Parameter Name="TimeZone" Type="String" />
</InsertParameters>
Again, what I need to know is how to I bind the selected value from the dropdownlist (ddlTimeZone) to #TimeZone
I tried:
<asp:DropDownList ID="ddlTimeZone" SelectedValue='<%# Bind("TimeZone") %>' runat="server">
</asp:DropDownList>
But that did not work. NOTE THAT I AM USING THE DROPDOWNLIST WITHIN A GRIDVIEW.
Try this way
var command = new SqlCommand("INSERT INTO [Companies] ([TimeZone]) VALUES ( #TimeZone)", connection);
command.Parameters.Add(new SqlParameter("#TimeZone", valuetopass));