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"
Related
The ultimate goal of what I am trying to accomplish is this:
Button at the bottom of a material order form Inserts a new record in the material order table with the ProjectID and current date. After the record is inserted, redirect the page to the new order id so it can be modified.
If I take out the OnInserted method that is supposed to grab the SCOPE_IDENTITY() output of the insert, the record inserts fine, but with the call, I keep getting "SQLParameter with ParameterName 'NewOrderID' is not contained by this SqlParameterCollection"
ASPX Formview
<asp:FormView ID="FvFooter" runat="server" DataKeyNames="OrderID"
DataSourceID="FvMatOrdersSQL" ForeColor="#333333" OnItemCommand="FvFooter_OnItemCommand">
<ItemTemplate>
<br/>
<b>Notes</b>
<br/>
<asp:Label ID="TxtNotes" runat="server" BorderStyle="Solid" BorderWidth="1"
Text='<%# Eval("Notes").ToString().Replace(Environment.NewLine, "<br />") %>'/>
<br/>
<asp:LinkButton ID="LbEditNotes" runat="server" CssClass="NoPrint"
CausesValidation="False" CommandName="Edit" Text="Edit"/>
<br/>
<br/>
<asp:Button ID="DeleteButton" runat="server" CausesValidation="False"
CssClass="NoPrint" CommandName="DeleteOrder" Text="Delete"/>
<asp:Button ID="NewButton" runat="server" CausesValidation="True"
CssClass="NoPrint" CommandName="NewOrder" Text="New Order"/>
<asp:Button ID="EmailButton" runat="server" CausesValidation="True"
CssClass="NoPrint" CommandName="Email" Text="Email"/>
</ItemTemplate>
</asp:FormView>
SQL DataSource
<asp:SqlDataSource ID="FvMatOrdersSQL" runat="server" ConnectionString="<%$ ConnectionStrings:ProjectLogicTestConnectionString %>"
SelectCommand="SELECT mo.OrderID, mo.ProjectID, p.ProjectName, mo.OrderedByEmpID, emp.Name,
mo.OrderDate, mo.DateNeeded, mo.ReasonID, mor.Description, mo.Notes
FROM tblMatOrder AS mo
LEFT OUTER JOIN tblMatOrderReason AS mor ON mo.ReasonID = mor.ReasonID
INNER JOIN tblProject AS p ON mo.ProjectID = p.ProjectID
LEFT OUTER JOIN tblEmployee AS emp ON mo.OrderedByEmpID = emp.EmployeeID
WHERE mo.OrderID = #OrderID"
DeleteCommand="DELETE FROM tblMatOrder WHERE OrderID = #OrderID"
InsertCommand="INSERT INTO tblMatOrder (OrderDate, ProjectID) VALUES (#OrderDate, #ProjectID);
SELECT #NewOrderID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE tblMatOrder SET OrderDate = #OrderDate, OrderedByEmpID = #OrderedByEmpID,
DateNeeded = #DateNeeded, ReasonID = #ReasonID, Notes = #Notes
WHERE OrderID = #OrderID"
OnInserted="FvMatOrdersSQL_OnInserted">
<SelectParameters>
<asp:RouteParameter Name="OrderID" Type="Int32" RouteKey="OrderID"/>
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="OrderID" Type="Int32" DefaultValue="0"/>
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="OrderDate" Type="DateTime"/>
<asp:Parameter Name="ProjectID" Type="Int32"/>
<asp:Parameter Direction ="Output" Name="NewOrderID" Type="Int32" DefaultValue="0"/>
</InsertParameters>
<UpdateParameters>
<asp:RouteParameter Name="OrderID" Type="Int32" RouteKey="OrderID"/>
<asp:Parameter Name="OrderDate" Type="DateTime"/>
<asp:Parameter Name="OrderedByEmpID" Type="Int32"/>
<asp:Parameter Name="DateNeeded" Type="DateTime"/>
<asp:Parameter Name="ReasonID" Type="Int32"/>
<asp:Parameter Name="Notes" Type="String"/>
</UpdateParameters>
</asp:SqlDataSource>
On Button Click codebehind
protected void FvFooter_OnItemCommand(object sender, FormViewCommandEventArgs e)
{
switch (e.CommandName)
{
case "DeleteOrder":
// Confirmation stuff here
break;
case "NewOrder" when Page.IsValid:
Label lblProjectId = (Label)FvHeader.FindControl("LblProjectID");
String strOrderDate = DateTime.Now.ToShortDateString();
FvMatOrdersSQL.InsertParameters.Clear();
FvMatOrdersSQL.InsertParameters.Add("ProjectID", lblProjectId.Text);
FvMatOrdersSQL.InsertParameters.Add("OrderDate", strOrderDate);
FvMatOrdersSQL.Insert();
break;
case "Email" when Page.IsValid:
break;
}
}
OnInserted codebehind
protected void FvMatOrdersSQL_OnInserted(object sender, SqlDataSourceStatusEventArgs e)
{
String strOrderId = e.Command.Parameters["#NewOrderID"].Value.ToString();
Response.Redirect("MatOrderDetails.aspx?OrderID=" + strOrderId);
}
I've tried to base as much of my code on the example here https://msdn.microsoft.com/en-us/library/ms228051.aspx but apparently I'm missing something.
I've put yr code and have created a db close to yr select to figure out yr problem, I have to admit it wasn't easy :) please
change this
FvMatOrdersSQL.InsertParameters.Clear();
FvMatOrdersSQL.InsertParameters.Add("ProjectID", lblProjectId.Text);
FvMatOrdersSQL.InsertParameters.Add("OrderDate", strOrderDate);
To:
FvMatOrdersSQL.InsertParameters["ProjectID"].DefaultValue = lblProjectId.Text;
FvMatOrdersSQL.InsertParameters["OrderDate"].DefaultValue = strOrderDate;
Don't remove the params which you've already created in the UI!
I have a GridView which has two session vairables used to filter the select statement (TimeStart and TimeFinish). I have a default value for these, which displays the correct information in the GridView.
I have two ASP TextBoxes with TextMode set to Time which I need to update these values. These update the session variables (have set a label's value to check), but do not update the select statement of my GridView.
I've done something Identical for another GridView on the same page, the only difference being that the session variable in an Int32 and being set from a GridView's IndexChanged event, and am confused as to why it's not working for this one.
Source for GridView:
<asp:GridView ID="gvAvailableVets" runat="server" AutoGenerateColumns="False" DataKeyNames="VetID" DataSourceID="AvailableVetsDataSource">
<Columns>
<asp:BoundField DataField="VetID" HeaderText="VetID" ReadOnly="True" SortExpression="VetID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="MobileNumber" HeaderText="MobileNumber" SortExpression="MobileNumber" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="AvailableVetsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:VetPracticeConnectionString %>" SelectCommand="SELECT DISTINCT Veternarians.VetID, FirstName, LastName, MobileNumber FROM dbo.Veternarians
INNER JOIN dbo.VetHours
ON Veternarians.VetID = VetHours.VetID
INNER JOIN dbo.Appointments
ON Veternarians.VetID = Appointments.VetID
WHERE #beginTime > VetHours.StartTime
AND #endTime < VetHours.EndTime
AND (#beginTime > Appointments.EndTime
OR #endTime < Appointments.BeginTime) ">
<SelectParameters>
<asp:SessionParameter DefaultValue="9:00" Name="beginTime" SessionField="TimeStart" Type="String" />
<asp:SessionParameter DefaultValue="10:00" Name="endTime" SessionField="TimeFinish" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
C# code behind for the TextBoxes:
protected void txtTimeBegin_TextChanged(object sender, EventArgs e) {
Session["TimeStart"] = txtTimeBegin.Text;
// Used for debugging
lblDebug.Text = Session["TimeStart"].ToString();
}
protected void txtTimeEnd_TextChanged(object sender, EventArgs e) {
Session["TimeFinish"] = txtTimeEnd.Text;
}
Try to rebind your Gridview when any textbox value changed.
protected void txtTimeBegin_TextChanged(object sender, EventArgs e)
{
Session["TimeStart"] = txtTimeBegin.Text;
gvAvailableVets.DataBind();
// Used for debugging
lblDebug.Text = Session["TimeStart"].ToString();
}
protected void txtTimeEnd_TextChanged(object sender, EventArgs e)
{
Session["TimeFinish"] = txtTimeEnd.Text;
gvAvailableVets.DataBind();
}
I'm using a Textbox and a DropDownList to filter database searches. I'm using an SQLDataSource with a blank SelectCommand and then setting the command in the codebehind depending on what the user has typed in and what is selected in the DropDownList. My IF statements in the codebehind only work if txtFindBook != "".
Before I explain anymore here is my code:
Default.aspx
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<div class="jumbotron">
<h1>Find a book...</h1>
<p>
<asp:TextBox ID="txtFindBook" runat="server" Width="700px"></asp:TextBox>
<asp:DropDownList ID="ddlGenres" runat="server"></asp:DropDownList>
<asp:Button ID="btnFindBook" runat="server" Text="Search" OnClick="btnFindBook_Click" Height="36px" />
<p>Enter your search terms in the box above, then click "Search" to begin your search.</p>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</div>
<div class="searchresults">
<asp:GridView ID="gvSearchResults" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDataSourceSearchResults">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True" InsertVisible="False" SortExpression="ID"></asp:BoundField>
<asp:BoundField DataField="BookID" HeaderText="BookID" SortExpression="BookID"></asp:BoundField>
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title"></asp:BoundField>
<asp:BoundField DataField="Author" HeaderText="Author" SortExpression="Author"></asp:BoundField>
<asp:BoundField DataField="ISBN_10" HeaderText="ISBN_10" SortExpression="ISBN_10"></asp:BoundField>
<asp:BoundField DataField="ISBN_13" HeaderText="ISBN_13" SortExpression="ISBN_13"></asp:BoundField>
<asp:BoundField DataField="Dewey" HeaderText="Dewey" SortExpression="Dewey"></asp:BoundField>
<asp:BoundField DataField="Genre" HeaderText="Genre" SortExpression="Genre"></asp:BoundField>
<asp:CheckBoxField DataField="isCheckedOut" HeaderText="isCheckedOut" SortExpression="isCheckedOut"></asp:CheckBoxField>
<asp:BoundField DataField="Checked_Out_To_Whome" HeaderText="Checked_Out_To_Whome" SortExpression="Checked_Out_To_Whome"></asp:BoundField>
<asp:BoundField DataField="Due_Date" HeaderText="Due_Date" SortExpression="Due_Date"></asp:BoundField>
</Columns>
</asp:GridView>
<asp:SqlDataSource runat="server" ID="SqlDataSourceSearchResults" ConnectionString='<%$ ConnectionStrings:DefaultConnection %>' SelectCommand="">
<SelectParameters>
<asp:ControlParameter ControlID="txtFindBook" PropertyName="Text" Name="Title" Type="String"></asp:ControlParameter>
<asp:ControlParameter ControlID="ddlGenres" PropertyName="SelectedValue" DefaultValue="Select Genre" Name="Genre" Type="String"></asp:ControlParameter>
</SelectParameters>
</asp:SqlDataSource>
</div>
Default.aspx.cs
public partial class _Default : Page
{
static string connString = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
SqlConnection conn = new SqlConnection(connString);
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
/*There is no point in populating
the dropdownlist everytime there
is a post back. */
populateddlGenres();
}
}
protected void btnFindBook_Click(object sender, EventArgs e)
{
if (txtFindBook.Text != "" && ddlGenres.SelectedItem.Text != "Select Genre")
{
SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books] WHERE (([Title] LIKE '%' + #Title + '%') AND ([Genre] = #Genre)) ORDER BY [Title]";
Label1.Text = "If Statement 1.";
}
else if (txtFindBook.Text == "" && ddlGenres.SelectedItem.Text != "Select Genre")
{
Label1.Text = "If Statement 2.";
SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books] WHERE ([Genre] = #Genre)";
}
else if (txtFindBook.Text == "" && ddlGenres.SelectedItem.Text == "Select Genre")
{
SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books]";
Label1.Text = "If Statement 3.";
}
else if(txtFindBook.Text != "" && ddlGenres.SelectedItem.Text == "Select Genre")
{
SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books] WHERE ([Title] LIKE '%' + #Title + '%') ORDER BY [Title]";
Label1.Text = "Original.";
}
}
private void populateddlGenres()
{
try
{
using (SqlConnection con = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand("SELECT * FROM Genres", con);
con.Open();
ddlGenres.DataSource = cmd.ExecuteReader();
ddlGenres.DataTextField = "GenreText";
//ddlGenres.DataValueField = ""; //We aren't using this because the text is it's own value.
ddlGenres.DataBind(); //MUST GO LAST!
}
}
catch (Exception ex)
{
// Handle the error
}
ddlGenres.Items.Insert(0, new ListItem("Select Genre", "0"));
}
}
Now If I add txtFindBook.text = "a"; at the beginning of If Statements 2 & 3 then it will actually populate gvSearchResults on PostBack.
Is there someway I can still have If statements 2 & 3 work while keeping txtFindBook.Text blank?
Modify your SqlDataSource by adding a default value of NULL to your Title property defined on it and that should do the trick. You will not need the labels, I didn't understand the label thing anyway.
<asp:SqlDataSource runat="server" ID="SqlDataSourceSearchResults" ConnectionString='<%$ ConnectionStrings:DefaultConnection %>' SelectCommand="">
<SelectParameters>
<asp:ControlParameter ControlID="txtFindBook" PropertyName="Text" DefaultValue="NULL" Name="Title" Type="String"></asp:ControlParameter>
<asp:ControlParameter ControlID="ddlGenres" PropertyName="SelectedValue" DefaultValue="Select Genre" Name="Genre" Type="String"></asp:ControlParameter>
</SelectParameters>
</asp:SqlDataSource>
I have an ASP.net with C# web app with an issue. On the app, the user can enter some data and click an "Add" button. This will generate a grid on the screen with the data the user just entered. There is also a text box for "Total Amount Requested". Below that, there is a label for "Remaining Amount". If the user puts 100.00 in the "Total Amount Requested" and then loads 75.00 into the grid, the "Remaining Amount" will show "25.00". This works fine. I added a delete row to the grid, so the user can delete specific rows. This also works. I added a _RowDeleted function to the grid, and then inserted the function to do the math for "Remaining Amount". Here is the issue:
When I delete the row, it deletes from the database, no issue. However, the label on the screen does not refresh. I put a stop in the code and walked through it. The script works, the label.text is loaded with what I expect, but it just won't refresh on screen. I've tried many different things but keep hitting a wall. Any help would be appreciated!
The Grid:
<dx:ASPxGridView ID="gridGL1" runat="server" AutoGenerateColumns="False"
DataSourceID="sdsGLData" KeyFieldName="GenLedgerID" OnRowDeleted="gridGL1_RowDeleted">
<Columns>
<dx:GridViewCommandColumn VisibleIndex="0" Caption=" " ButtonType="Button">
<DeleteButton Visible="True">
</DeleteButton>
</dx:GridViewCommandColumn>
<dx:GridViewDataTextColumn FieldName="GenLedgerID" Visible="false" VisibleIndex="1">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn FieldName="UnitNumber" VisibleIndex="2">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn FieldName="AccountNumber" VisibleIndex="3">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn FieldName="Amount" VisibleIndex="4">
</dx:GridViewDataTextColumn>
</Columns>
<SettingsBehavior ConfirmDelete="True" />
</dx:ASPxGridView>
The SDS:
<asp:SqlDataSource ID="sdsGLData" runat="server"
ConnectionString="<%$ ConnectionStrings:FEAPConnectionString %>"
ProviderName="<%$ ConnectionStrings:FEAPConnectionString.ProviderName %>"
SelectCommand="prcRequestGLList" SelectCommandType="StoredProcedure"
DeleteCommand="delete RequestsGL where GenLedgerID = #GenLedgerID">
<SelectParameters>
<asp:Parameter Direction="ReturnValue" Name="RETURN_VALUE" Type="Int32" />
<asp:ControlParameter ControlID="lblUserID" Name="UserID" PropertyName="Text"
Type="String" />
<asp:ControlParameter ControlID="txtRequestDate" Name="RequestDate"
PropertyName="Text" Type="DateTime" />
</SelectParameters>
</asp:SqlDataSource>
The _RowDeleted
protected void gridGL1_RowDeleted(object sender, DevExpress.Web.Data.ASPxDataDeletedEventArgs e)
{
RemainingTotal();
}
The RemainingTotal():
protected void RemainingTotal()
{
TotalGLAmount();
decimal TotalReq;
decimal TotalGL;
// Total Requested Amount
if (txtTotalAmount.Text == "")
{
TotalReq = 0.00M;
}
else
{
TotalReq = Convert.ToDecimal(txtTotalAmount.Text);
}
// Total GL Amount
if (lblTotalGLAmount.Text == "")
{
TotalGL = 0.00M;
}
else
{
TotalGL = Convert.ToDecimal(lblTotalGLAmount.Text);
}
// Total Remaining Amount
if (TotalReq != TotalGL)
{
lblRemainingAmount.Text = Convert.ToString(TotalReq - TotalGL);
lblTest.Text = Convert.ToString(TotalReq - TotalGL);
if (TotalReq > TotalGL)
{
lblRemainingAmount.ForeColor = Color.Black;
}
else if (TotalReq < TotalGL)
{
lblRemainingAmount.ForeColor = Color.Red;
}
}
else
{
if (txtTotalAmount.Text != "")
{
lblRemainingAmount.Text = "<b>EVEN!</b>";
lblRemainingAmount.ForeColor = Color.Black;
lblTest.Text = "<b>EVEN!</b>";
}
else
{
lblRemainingAmount.Text = "0.00";
lblRemainingAmount.ForeColor = Color.Black;
lblTest.Text = "0.00";
}
}
}
Check these threads:
The concept of callbacks - Why is it impossible to update external control data during a callback to another control
ASPxGridView - How to update an external control during a callback
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