I'm using the BulkEditGridView control as discussed http://roohit.com/site/showArc.php?shid=bbb62, and it's perfect for my needs. The problem I'm having is that whenever I save, every visible row (I have paging enabled) gets updated. Stepping through the code I see that grid.DirtyRows.Count is equal to the number of items per page minus 1 when I click the save button.
I can't find where rows are set as dirty. Any suggestions where I can look?
My code-behind has only this:
using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Collections;
using System.Data.Common;
public partial class MSDS_MSDS_Admin_GridUpdate : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gridMSDS.DataKeyNames = new String[] { "id" };
gridMSDS.DataBind();
}
}
}
EDIT: Here is the aspx code.
<%# Page Language="C#" MasterPageFile="~/MSDS/MSDS.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="GridUpdate.aspx.cs" Inherits="MSDS_MSDS_Admin_GridUpdate" Title="Untitled Page" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<%# Register Assembly="RealWorld.Grids" Namespace="RealWorld.Grids" TagPrefix="cc2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="PageContent" runat="Server">
<br />
<asp:Button ID="btnSave" runat="server" Text="Save" Width="100%" />
<cc2:BulkEditGridView ID="gridMSDS" runat="server" AllowPaging="True" AllowSorting="True"
DataSourceID="sqlData" EnableInsert="False" InsertRowCount="1" PageSize="20"
SaveButtonID="btnSave" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" Visible="false"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="ChemicalTitle" HeaderText="ChemicalTitle" SortExpression="ChemicalTitle" />
<asp:TemplateField HeaderText="SheetDate" SortExpression="SheetDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SheetDate") %>' Width="85px"></asp:TextBox>
<cc1:CalendarExtender ID="TextBox1_CalendarExtender" runat="server" Enabled="True"
TargetControlID="TextBox1">
</cc1:CalendarExtender>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("SheetDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Filename" HeaderText="Filename" SortExpression="Filename" />
<asp:BoundField DataField="Manufacturer" HeaderText="Manufacturer" SortExpression="Manufacturer" />
<asp:BoundField DataField="UsageDept" HeaderText="UsageDept" SortExpression="UsageDept" />
<asp:TemplateField HeaderText="Notes" SortExpression="Notes">
<EditItemTemplate>
<asp:TextBox ID="TextBox5" runat="server" Text='<%# Bind("Notes") %>' TextMode="MultiLine"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label6" runat="server" Text='<%# Bind("Notes") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Status" SortExpression="Status">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="sqlStatus" DataTextField="DisplayValue"
DataValueField="Value" SelectedValue='<%# Bind("Status") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="sqlStatus" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
SelectCommand="getOptionList" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="msds_Status" Name="ListName" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="sqlStatus" disabled="true"
BackColor="White" DataTextField="DisplayValue" DataValueField="Value" SelectedValue='<%# Bind("Status") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="sqlStatus" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
SelectCommand="getOptionList" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="msds_Status" Name="ListName" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Health" SortExpression="Health">
<EditItemTemplate>
<center>
<asp:TextBox ID="TextBox2" runat="server" Style="text-align: center" Text='<%# Bind("Health") %>'
Width="25px"></asp:TextBox>
</center>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Health") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fire" SortExpression="Fire">
<EditItemTemplate>
<center>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("Fire") %>' Width="25px"></asp:TextBox></center>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Bind("Fire") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Reactivity" SortExpression="Reactivity">
<EditItemTemplate>
<center>
<asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("Reactivity") %>' Width="25px"></asp:TextBox></center>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label5" runat="server" Text='<%# Bind("Reactivity") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DateUpdated" HeaderText="DateUpdated" SortExpression="DateUpdated"
ReadOnly="True" />
<asp:BoundField DataField="UpdatedBy" ReadOnly="True" HeaderText="UpdatedBy" SortExpression="UpdatedBy" />
</Columns>
</cc2:BulkEditGridView>
<asp:SqlDataSource ID="sqlData" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
SelectCommand="SELECT [ID], [ChemicalTitle], dbo.dateOnly([SheetDate]) As [SheetDate], [Filename], [Manufacturer], [UsageDept], [Notes], isnull([Status], 4) as [Status], [Health], [Fire], [Reactivity], [DateUpdated], [UpdatedBy] FROM [msds_Sheets] ORDER BY [ChemicalTitle]"
UpdateCommand="msds_UpdateSheet" UpdateCommandType="StoredProcedure">
<UpdateParameters>
<asp:Parameter Name="ID" Type="Int32" />
<asp:Parameter Name="ChemicalTitle" Type="String" />
<asp:Parameter Name="SheetDate" DbType="DateTime" />
<asp:Parameter Name="Filename" Type="String" />
<asp:Parameter Name="Manufacturer" Type="String" />
<asp:Parameter Name="UsageDept" Type="String" />
<asp:Parameter Name="Notes" Type="String" />
<asp:Parameter Name="Status" Type="Int16" />
<asp:Parameter Name="Health" Type="Int16" />
<asp:Parameter Name="Fire" Type="Int16" />
<asp:Parameter Name="Reactivity" Type="Int16" />
<asp:ProfileParameter Name="UpdatedBy" Type="String" PropertyName="Username" />
</UpdateParameters>
</asp:SqlDataSource>
</asp:Content>
Testing Procedure is as follows:
-Load the page.
-Edit something in the first row.
-Click save button.
The code you have posted looks fine. My test code is almost identical to yours, but I cannot produce the unwanted results you are seeing.
The most significant difference between your code and mine is that I don't have the code for your master page. My master page is the default page created by VS 2008. Other than that, the differences are in the SQL and the underlying database. Specifically, I am not using any stored procedures, and I have made reasonable assumptions about the data types involved: the ID is int, Status is smallint, SheetDate is Date, DateUpdated is DateTime, and everything else is varchar.
EDIT: Your SheetDate appears to be just the date portion of an underlying DateTime value from the database. The fact that your query transforms the underlying data value for display purposes is not relevant, because the grid view can't tell that it is getting a modified value. END OF EDIT
Here are a few suggestions for diagnosing the problem:
Test without master page, or with a
very simple dummy master page that is
guaranteed not to have scripts that
interact with the BulkEditGridView.
Since the ToolkitScriptManager is
apparently on your master page, you will
need to either move the script
manager control to the page itself,
or else temporarily get rid of the
CalendarExtender element, which
requires the script manager.
Temporarily replace the Status
template field with a bound data
field, to eliminate possibility of
interaction with the DropDownList.
The drop down list did not cause
problems in my tests, but there may
be subtle differences between your
code and mine.
If neither of these help, then a possible cause is a problem in your
version of the BulkEditGridView.
EDIT - Additional suggestions for diagnosis:
Based on examination of the source code for BulkEditGridView, it appears that the code is properly tracking which rows of the grid are "dirty". Therefore, the most likely cause of a spurious dirty row is that one or more controls in the grid are incorrectly detecting a change to their data content. You can detect this in the debugger, using the source code for BulkEditGridView, rather than the pre-compiled DLL.
Set a breakpoint at the start of HandleRowChanged, the event handler which detects changes in any cell of the grid. By examining the sender parameter of that object in the debugger, you can tell which controls in the grid are undergoing value changes. In particular, you will be able to tell which controls, if any, are incorrectly triggering a value change event.
Once you determine which control(s) are incorrectly reporting that their value has changed, you can focus on why this is happening.
END OF EDIT
Some other suggestions to improve the code are as follows. These will not solve the original problem, but will make the code cleaner:
In all of the template fields, remove the ItemTemplates. They can never be used, since the BulkEditGridView forces every row to be in the edit state.
In the code behind, the BindData()
call is not needed, since the source
data is specified in the declarative
markup, and therefore the grid view
control will automatically bind the
data.
I am not an expert in BulkEditGridView control, but this is what I found at Matt Dotson's blog entry
You may not be able to know that the row has been updated, unless you watch for the change explicitly. First, for each row add a change handler
protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
{
base.InitializeRow(row, fields);
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.Controls.Count > 0)
{
AddChangedHandlers(cell.Controls);
}
}
}
You can use this snippet
private void AddChangedHandlers(ControlCollection controls)
{
foreach (Control ctrl in controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).TextChanged += new EventHandler(this.HandleRowChanged);
}
else if (ctrl is CheckBox)
{
((CheckBox)ctrl).CheckedChanged += new EventHandler(this.HandleRowChanged);
}
else if (ctrl is DropDownList)
{
((DropDownList)ctrl).SelectedIndexChanged += new EventHandler(this.HandleRowChanged);
}
}
}
Then you define a dirty row list and add rows that needs to be updated there (in the event handler)
private List<int> dirtyRows = new List<int>();
void HandleRowChanged(object sender, EventArgs args)
{
GridViewRow row = ((Control) sender).NamingContainer as GridViewRow;
if (null != row && !dirtyRows.Contains(row.RowIndex))
{
dirtyRows.Add(row.RowIndex);
}
}
Finally, to commit changes, iterate through all the dirty rows and save changes
public void Save()
{
foreach (int row in dirtyRows)
{
this.UpdateRow(row, false);
}
dirtyRows.Clear();
}
And here is your ASPX code
<asp:Button runat="server" ID="SaveButton" Text="Save Data" />
<blog:BulkEditGridView runat="server" id="EditableGrid" DataSourceID="AdventureWorks" AutoGenerateColumns="False" DataKeyNames="LocationID" SaveButtonID="SaveButton" >
<Columns>
<asp:BoundField DataField="LocationID" HeaderText="LocationID" InsertVisible="False" ReadOnly="True" SortExpression="LocationID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Availability" HeaderText="Availability" SortExpression="Availability" />
<asp:BoundField DataField="CostRate" HeaderText="CostRate" SortExpression="CostRate" />
</Columns>
</blog:BulkEditGridView>
Related
O' Great and Powerful Wizards of Visual Studio,
(asp.net C#)
I have 2 gridviews of employee skills. To simplify the question, I have only the employee badge_ID (123 = John Doe) and the skill_ID (34 = knowledge of CNC lathe usage). My database table looks like this:
table: empl_skills
ref_no (key) badge_ID Skill_ID prof_value Need_Improve skill_update
------ -------- -------- ------------ ------------ ------------
1 123 35 Expert No 10/08/20
2 123 36 Proficient No 10/08/20
3 123 37 Expert No 10/08/20
4 319 12 Expert No 10/08/20
5 319 60 Basic Yes 10/08/20
6 225 62 Proficient No 10/08/20
7 225 71 Proficient No 10/08/20
The first ref_no column is the primary key that is (1,1) identity
The setup is quite simple. The first Gridview1 only displays the badge_ID and SELECT so you can pick the employee. Once selected, Gridview1 hides and the second Gridview2 displays only that employee's skills with the EDIT and DELETE commandfields turned on. This was all working great and I built the code in the designer, all working, in less than 5 minutes.
Now I want to add an INSERT function. I was going to do that in a FooterTemplate with an INSERT linkbutton in the primary key column (ref_no) and textboxes in the other columns for data entry. So to do that I first need to convert the default asp:boundfields to asp:templatefields. As soon as I did that conversion of the fields, my EDIT and DELETE functions in the commandfield stopped working and I can't figure out why.
It really is quite maddening because in ALL of these other webforms below - more than 30 times, I have converted the default asp:boundfields to asp:templatefields and I've never had this problem.
Hopefully, someone can tell me what's going on, please?
Here's Gridview1 to select an employee (I removed the styling stuff)
<asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#999999"
BorderStyle="Solid" BorderWidth="1px"
CellPadding="3" CssClass="centerMyHeader" DataKeyNames="badge_ID"
DataSourceID="SqlDataSource1" OnPreRender="GridView1_PreRender"
ForeColor="Black" GridLines="Vertical">
<AlternatingRowStyle BackColor="#EEEEEE" />
<Columns>
<asp:CommandField ShowSelectButton="True" />
</Columns>
</asp:GridView>
Here's Gridview2 with the boundfields converted to templatefields:
<asp:GridView ID="GridView2" runat="server" BackColor="White" BorderColor="#999999"
BorderStyle="Solid" BorderWidth="1px"
CellPadding="3" CssClass="centerMyHeader" DataSourceID="SqlDataSource2"
ForeColor="Black" GridLines="Vertical" AutoGenerateColumns="False">
<AlternatingRowStyle BackColor="#EEEEEE" />
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:TemplateField HeaderText="ref_no" InsertVisible="False" SortExpression="ref_no">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ref_no") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label6" runat="server" Text='<%# Bind("ref_no") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="badge_ID" SortExpression="badge_ID">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("badge_ID") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("badge_ID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="skill_ID" SortExpression="skill_ID">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("skill_ID") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("skill_ID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="prof_value" SortExpression="prof_value">
<EditItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("prof_value") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("prof_value") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="need_improve" SortExpression="need_improve">
<EditItemTemplate>
<asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("need_improve") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Bind("need_improve") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="skill_update" SortExpression="skill_update">
<EditItemTemplate>
<asp:TextBox ID="TextBox5" runat="server" Text='<%# Bind("skill_update") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label5" runat="server" Text='<%# Bind("skill_update") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The CodeFile just hides whichever gridviews are supposed to show or not show:
protected void GridView1_PreRender(object sender, EventArgs e)
{
if (GridView1.SelectedRow != null)
{
//when one employee is selected
GridView1.Visible = false;
Label1.Visible = false;
GridView2.Visible = true;
Label2.Visible = true;
btnReload2.Visible = true;
}
else
{
//when the selection list is up (no one selected yet)
GridView2.Visible = false;
Label2.Visible = false;
GridView1.Visible = true;
Label1.Visible = true;
btnReload2.Visible = false;
}
}
While it only took me 5 minutes to initially build the gridviews (you can see how many times I've done this), I've spent the last two days trying to make this work with templatefields. Can anyone help, please? Thanks, John
EDIT: Sorry - I didn't say what happens.
Edit linkbutton: On a row when I click Edit, the textboxes appear and I can change the data in any column. Then I click Update. RESULT: the change does NOT take place and no errors are thrown. Essentially, nothing happens
Delete Linkbutton: when clicking Delete, the webform throws the error: Must declare the scalar variable "#ref_no". Not sure what they mean by that or moreover where? Here is SqlDataSource2 with ref_no declared in the UpdateParameters:
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:TrainingDBConnection %>"
DeleteCommand="DELETE FROM [empl_skills] WHERE [ref_no] = #ref_no"
InsertCommand="INSERT INTO [empl_skills] ([badge_ID], [skill_ID], [need_improve], [skill_update], [prof_value])
VALUES (#badge_ID, #skill_ID, #need_improve, #skill_update, #prof_value)"
SelectCommand="SELECT [ref_no], [badge_ID], [skill_ID], [need_improve], [skill_update], [prof_value] FROM [empl_skills] WHERE ([badge_ID] = #badge_ID)"
UpdateCommand="UPDATE [empl_skills] SET [badge_ID] = #badge_ID, [skill_ID] = #skill_ID, [need_improve] = #need_improve, [skill_update] = #skill_update,
[prof_value] = #prof_value WHERE [ref_no] = #ref_no">
<DeleteParameters>
<asp:Parameter Name="ref_no" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="badge_ID" Type="Int32" />
<asp:Parameter Name="skill_ID" Type="Int32" />
<asp:Parameter Name="need_improve" Type="String" />
<asp:Parameter DbType="Date" Name="skill_update" />
<asp:Parameter Name="prof_value" Type="String" />
</InsertParameters>
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="badge_ID" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="badge_ID" Type="Int32" />
<asp:Parameter Name="skill_ID" Type="Int32" />
<asp:Parameter Name="need_improve" Type="String" />
<asp:Parameter DbType="Date" Name="skill_update" />
<asp:Parameter Name="prof_value" Type="String" />
<asp:Parameter Name="ref_no" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
Thanks.
nevermind - I guess there's no interest. I converted the second detail Gridview to a DetailsView which already has Edit, Delete, and Insert commandfields. Problem solved - no custom code. Works flawlessly. I guess no one really cares about webforms anymore, too old.
I am trying to compute the column in real time meaning the calculation should be seen before an edit link is clicked. The weight first half is already found in the gridview.
The gridview is then edited to add the rating first half. the 2, weight first half and rating first half needs to be multiplied to get the result that is score first half and score first half I made it a ReadOnly.
Now I want the score first half to be saved in the SQL Server database. Mind you I already have the update command that the SqlDataSource generates.
Here is my markup:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
DataKeyNames="P_C_ID"
DataSourceID="SqlDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:TemplateField HeaderText="P_C_ID"
InsertVisible="False" SortExpression="P_C_ID">
<EditItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Eval("P_C_ID") %>'>
</asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("P_C_ID") %>'>
</asp:Label>
</ItemTemplate>
<asp:TemplateField HeaderText="WEIGHT_FIRST_HALF"
SortExpression="WEIGHT_FIRST_HALF">
<EditItemTemplate>
<asp:TextBox ID="TextBox5"
runat="server"
ReadOnly="True"
Text='<%# Bind("WEIGHT_FIRST_HALF") %>'>
</asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label6"
runat="server"
Text='<%# Bind("WEIGHT_FIRST_HALF") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<ItemTemplate>
<asp:Label ID="Label9"
runat="server"
Text='<%# Bind("SCORE_FIRST_HALF") %>'>
</asp:Label>
</ItemTemplate>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:AWPConnectionString5 %>"
UpdateCommand="UPDATE [Performance_Rating_2] SET [WEIGHT FIRST HALF] = #WEIGHT_FIRST_HALF, [RATING FIRST HALF] = #RATING_FIRST_HALF, [SCORE FIRST HALF], [RATING FIRST HALF] = #RATING_FIRST_HALF = #SCORE_FIRST_HALF WHERE [P_C_ID] = #P_C_ID">
<asp:Parameter Name="WEIGHT_FIRST_HALF"
Type="Decimal" />
<UpdateParameters>
<asp:Parameter Name="RATING_FIRST_HALF"
Type="Int32" />
<asp:Parameter Name="SCORE_FIRST_HALF"
Type="Decimal" />
</UpdateParameters>
Okay folks the program is long. I just took part that is not working fine. But should you need clarity do not hesitate to ask for clarity. Right now only the weight and rating is being saved. the computed is not saved at all. I actually do not want to write it in C# codes as I need results in real time
How do I send mltiple users message using a griview which should be connected to two tables namely login(from where usernames will be retrieved and shown) and then the second table message (where a message is to be stored for particular usernames). I have connected it to login but I am not able to insert values into message table. Message table has msg_id , username and message columns.
Here is the design:
.aspx
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
EnableModelValidation="True" DataSourceID="SqlDataSource1"
onrowcommand="GridView2_RowCommand">
<Columns>
<asp:BoundField DataField="username" HeaderText="username"
SortExpression="username" />
<asp:BoundField DataField="password" HeaderText="password"
SortExpression="password" />
<asp:BoundField DataField="utype" HeaderText="utype" SortExpression="utype" />
<asp:BoundField DataField="ptype" HeaderText="ptype" SortExpression="ptype" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:AutomobileConnectionString14 %>"
SelectCommand="SELECT * FROM [login] WHERE ([utype] LIKE '%' + #utype + '%')">
<SelectParameters>
<asp:Parameter DefaultValue="U" Name="utype" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</asp:Content>
aspx.cs code
protected void GridView2_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("cc"))
{
TextBox txt1 = (TextBox)GridView2.FooterRow.FindControl("TextBox1");
foreach(GridView gr in GridView2.Rows)
{
CheckBox chk = (CheckBox)gr.FindControl("CheckBox1");
if (chk.Checked)
{
Object ob = GridView2.DataKeys[gr.RowIndex].Value;
}
now I am stuck her how can I insert values into other table message when it is already connected to Login table. Help me what I want to accomplish here is send message to checked users.
Try below :
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" DataKeyNames="userId"
OnRowCommand="GridView2_RowCommand" OnRowEditing="GridView2_RowEditing" OnRowUpdated="GridView2_RowUpdated" OnRowUpdating="GridView2_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="Username">
<ItemTemplate>
<asp:Label Text='<%# Eval("username") %>' runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="password" HeaderText="password"
SortExpression="password" />
<asp:BoundField DataField="utype" HeaderText="utype" SortExpression="utype" />
<asp:BoundField DataField="ptype" HeaderText="ptype" SortExpression="ptype" />
<asp:TemplateField>
<ItemTemplate>
<asp:Label Text='<%# Eval("messgae") %>' runat="server"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtMsg" runat="server"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chk" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
On RowDataBound event to set the edit textbox for message by find control.
And refer to code for inline editing on check box click.
http://www.c-sharpcorner.com/UploadFile/9f0ae2/gridview-edit-delete-and-update-in-Asp-Net/
http://www.codeproject.com/Articles/23471/Editable-GridView-in-ASP-NET
.NET 4 ASP.NET
I have a DetailsView that is displaying an entity framework record for a table that has a linked lookup table. I have an asp:BoundField with the datafield set as "linkedTable.Field" and it displays a value.
<asp:BoundField DataField="linkedTable.Field" HeaderText="linkedTable.Field"
SortExpression="linkedTable.Field" />
I am trying to use that value in an asp:TemplateField but when I try to get it using:
<asp:TemplateField HeaderText="Field" SortExpression="linkedTable.Field" >
<EditItemTemplate>
<asp:Label runat="server" ID="lblField" Text='<%# Bind("linkedTable.Field") %>' />
</EditItemTemplate>
</asp:TemplateField>
Nothing shows up in the label. I can change the Bind() to a field that is not part of the linked table and it works (i.e. the "ID" field). My problem is I don't understand why the linkedtable.Field value shows up in one context and not in the other.
FYI, my data connection is a EntityDataSource
<asp:EntityDataSource ID="edsNYSEDaily" runat="server"
ConnectionString="name=ServerDBEntities"
DefaultContainerName="ServerDBEntities" EntitySetName="tblNYSE"
EntityTypeFilter="tblNYSE" EnableUpdate="True" EnableFlattening="true"
AutoGenerateWhereClause="True" Select="" Where="">
<WhereParameters>
<asp:QueryStringParameter DefaultValue="0" Name="ID"
QueryStringField="ID" Type="Int32" />
</WhereParameters>
Let me know if you need any other information. I am stuck
Ok, discovered the problem:
Needed to add Include="linkedTable" to the EntityDataSource tag. Still not sure why it was even working in the <asp:DataBound /> tag.
Source for the answer: forums.asp.net
Copy of the text:
you should start here: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.entitydatasource.include.aspx
notice that, you won't be able to Bind (I mean two-way data-binding) the related entities (see the remarks there).
and, you'd have to use a TemplateField for those properties.
see this example (I used the link table 'TableAB' for EntitySetName and included the other two):
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="EntityDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="IDA" HeaderText="IDA" SortExpression="IDA" />
<asp:BoundField DataField="IDB" HeaderText="IDB" SortExpression="IDB" />
<asp:TemplateField HeaderText="TableA Name">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("TableA.NameA") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="TableB Name">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("TableB.NameB") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:EntityDataSource ID="EntityDataSource1" runat="server" ConnectionString="name=ABLinkEntities"
DefaultContainerName="ABLinkEntities" EnableDelete="True" EnableFlattening="False"
EnableInsert="True" EnableUpdate="True" EntitySetName="TableABs" Include="TableA,TableB">
</asp:EntityDataSource>
you'll have to re-consider the updates and deletes, you could do them manually.
Background
I have a GridView that builds a table using an ObjectDataSource. This source uses web services for both the select and update segments. Under the edit section, when clicked, has a DropDownList appear for the two columns that need to be editable. The DropDownLists both use separate ObjectDataSources storing WebServices that obtain the values meant to be stored in this DropDownList.
Currently working
At the moment, all of the above works. When I load the page, the table comes up with the proper data. When I click on the edit button, the two DropDownLists come up with the proper data stored in them from the WebService.
The Problem
When I select an option to update the DB or when I select cancel, the page throws an error and fails. I am not entirely sure why this happens, other than that it has to do with the binding not being handled correctly. I would like to know how to bind the values obtained from the DropDownList to be used when updating the database?
Below you will find what i have tried so far:
<asp:GridView ID="GridViewHolder"
runat="server"
AllowPaging="True"
AutoGenerateColumns="False"
BackColor="Transparent"
BorderColor="#999999"
BorderStyle="Ridge"
BorderWidth="3px"
CellPadding="4"
CellSpacing="2"
DataSourceID="MachineDataSet"
ForeColor="Black"
HeaderStyle-HorizontalAlign="Center"
HorizontalAlign="Center"
RowStyle-HorizontalAlign="Center" Width="574px"
OnRowUpdating="GridViewHolder_Updating"
OnRowCancelingEdit="GridViewHolder_Canceling"
OnRowUpdated="GridViewHolder_Updated"
OnRowEditing="GridViewHolder_Editing">
<RowStyle BackColor="Transparent" HorizontalAlign="Center" />
<Columns>
<asp:BoundField DataField="ID"
HeaderText="ID"
SortExpression="ID"
Visible="False" />
<asp:BoundField DataField="SiteName"
HeaderText="Site Name"
SortExpression="SiteName"
ReadOnly="true" />
<asp:BoundField DataField="Name"
HeaderText="Machine Name"
ReadOnly="true"
SortExpression="Name" />
<asp:TemplateField HeaderText="Machine Type" SortExpression="MachineType">
<EditItemTemplate>
<asp:ObjectDataSource ID="GetMachineType"
runat="server"
SelectMethod="GetMachineTypeList"
TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
<SelectParameters>
<asp:Parameter Name="siteid" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:DropDownList ID="MachineTypeDropDown"
runat="server"
AppendDataBoundItems="True"
DataSourceID="GetMachineType"
DataTextField="Name"
DataValueField="ID"
Height="21px"
Width="217px">
<asp:ListItem Enabled="true"
Text="Select a Machine Type.">
</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("MachineType") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Machine Model" SortExpression="MachineModel">
<EditItemTemplate>
<asp:ObjectDataSource ID="GetMachineModel"
runat="server"
SelectMethod="GetMachineModelList"
TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
<SelectParameters>
<asp:Parameter Name="siteid" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:DropDownList ID="MachineModelDropDown"
runat="server"
AppendDataBoundItems="True"
DataSourceID="GetMachineModel"
DataTextField="Name"
DataValueField="ID"
Height="21px"
Width="217px">
<asp:ListItem Enabled="true"
Text="Select a Machine Model."
Value="NULL">
</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2"
runat="server"
Text='<%# Bind("MachineModel") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Button" ShowEditButton="True" />
</Columns>
<FooterStyle BackColor="Transparent" />
<PagerStyle BackColor="Transparent"
ForeColor="Black"
HorizontalAlign="Left" />
<SelectedRowStyle BackColor="Transparent"
Font-Bold="True"
ForeColor="White" />
<HeaderStyle BackColor="Black"
Font-Bold="True"
ForeColor="White"
HorizontalAlign="Center" />
</asp:GridView>
Where the problem seems to lie, is in this area below:
<asp:TemplateField HeaderText="Machine Type"
SortExpression="MachineType">
<EditItemTemplate>
<asp:ObjectDataSource ID="GetMachineType"
runat="server"
SelectMethod="GetMachineTypeList"
TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
<SelectParameters>
<asp:Parameter Name="siteid" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:DropDownList ID="MachineTypeDropDown"
runat="server"
DataSourceID="GetMachineType"
DataTextField="Name"
DataValueField="ID"
Height="21px"
Width="217px"
AppendDataBoundItems="true">
<asp:ListItem Enabled="true"
Selected="True"
Text="Select a Machine Type.">
</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("MachineType") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Machine Model"
SortExpression="MachineModel">
<EditItemTemplate>
<asp:ObjectDataSource ID="GetMachineModel"
runat="server"
SelectMethod="GetMachineModelList"
<asp:TemplateField HeaderText="Machine Type" SortExpression="MachineType">
<EditItemTemplate>
<asp:ObjectDataSource ID="GetMachineType"
runat="server"
SelectMethod="GetMachineTypeList"
TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
<SelectParameters>
<asp:Parameter Name="siteid" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:DropDownList ID="MachineTypeDropDown"
runat="server"
AppendDataBoundItems="True"
DataSourceID="GetMachineType"
DataTextField="Name"
DataValueField="ID"
Height="21px"
Width="217px">
<asp:ListItem Enabled="true"
Text="Select a Machine Type.">
</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("MachineType") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Machine Model" SortExpression="MachineModel">
<EditItemTemplate>
<asp:ObjectDataSource ID="GetMachineModel"
runat="server"
SelectMethod="GetMachineModelList"
TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
<SelectParameters>
<asp:Parameter Name="siteid" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:DropDownList ID="MachineModelDropDown"
runat="server"
AppendDataBoundItems="True"
DataSourceID="GetMachineModel"
DataTextField="Name"
DataValueField="ID"
Height="21px"
Width="217px">
<asp:ListItem Enabled="true"
Text="Select a Machine Model."
Value="NULL">
</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2"
runat="server"
Text='<%# Bind("MachineModel") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Updated for bounty
My overall problem is: using the gridview, I am unable to get my edit, update, cancel buttons to work. So what I would like to also know since I am throwing a bounty on this is: how can I get these events to work properly using ObjectDataSources?
I already know that the web services work properly, I just do not know how to load the necessary parameters with the right data-values from the table. Any help or suggestions are greatly appreciated.
Error thrown at the moment:
Failed to load viewstate. The control tree into
which viewstate is being loaded must match the
control tree that was used to save viewstate
during the previous request. For example, when
adding controls dynamically, the controls added
during a post-back must match the type and
position of the controls added during the
initial request.
I am unsure as to how to get the update and cancel events to fire correctly, so I have been trying to use the OnRow* event handlers, but none of these work or fire, even when I set up a break point on a method just to see if the event will fire.
Update2
So as requested here is what i have for the code behind dealing with the the events i had thought might fire, (note: i've tried this with almost all of the other events). When i would run a debugger attaching the page to an asp.net process and click on the update button, cancel button, or edit button i would expect the page to go to the breakpoint, however this does not happen.
Note: I also know that the code behind is most likely incorrect, but i didn't want to fix any of that until i knew which event would be the right one that fires for update and cancel buttons.
protected void GridViewHolder_Updating(object sender, GridViewUpdateEventArgs e)
{
int machineid;
string machineTypeid;
string machineModelid;
GridViewRow row = (GridViewRow)GridViewHolder.Rows[e.RowIndex];
Label id = (Label)row.FindControl("ID");
DropDownList mType1 = GridViewHolder.Rows[e.RowIndex].FindControl("MachineTypeDropDown") as DropDownList;
e.NewValues["MachineType"] = mType1.SelectedValue;
DropDownList mType = (DropDownList)row.FindControl("Machine_Type");
DropDownList mModel = (DropDownList)row.FindControl("Machine_Model");
machineid = Convert.ToInt32(id);
machineTypeid = mType.DataValueField.ToString();
machineModelid = mModel.DataValueField.ToString();
inputsService.UpdateMachineTypes(machineid, machineTypeid);
inputsService.UpdateMachineModels(machineid, machineModelid);
}
protected void GridViewHolder_Updated(object sender, GridViewUpdatedEventArgs e)
{
}
/// <summary>
/// Handles the Click event of the cancel button under edit in the gridview control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewCancelEditEventArgs"/> instance containing the event data.</param>
protected void GridViewHolder_Canceling(object sender, GridViewCancelEditEventArgs e)
{
//reset the edit index
GridViewHolder.EditIndex = -1;
//Bind data to GridViewHolder
BindData();
}
protected void GridViewHolder_Editing(object sender, GridViewEditEventArgs e)
{
}
#endregion
#region Private Methods
private void BindData()
{
GridViewHolder.DataSource = Session["MachineTable"];
GridViewHolder.DataBind();
}
#endregion
Update 3
Okay you will find above the most recent attempt that i have done to try and get the update and cancel buttons to function properly in the gridview.
Any help or suggestions are greatly appreciated.
Thank you.
I would suspect that the ViewState error is being caused by code on the code-behind and is not being triggered by the GridView code you posted. Can your post the code-behind for your OnRow... methods and any Page_Load/Page_Init code?
Having said that, in order to get your updates to work for the DropDownList controls you'll need to add some code in the RowUpdating method. Here's a blog post by Peter Kellner, but the pertinent code is:
protected void GridViewIncomingUrls_RowUpdating(object sender, GridViewUpdateEventArgs e) {
DropDownList dropDownListUser = GridViewIncomingUrls.Rows[e.RowIndex].FindControl("MachineTypeDropDown") as DropDownList;
e.NewValues["MachineTypeID"] = dropDownListUser.SelectedValue;
}
Also, you may want to set the SelectedValue property of your dropwdowns, so that the previously selected value is pre-populated when the user hits the edit button:
<asp:DropDownList
ID="MachineModelDropDown"
SelectedValue='<%#Bind("MachineModelID") %>'
...
I've never seen an ObjectDataSource used inside a template - always controls explicitly populated / bound in ItemDataBound event of the grid.
Complex stuff like this, I would only use an ItemTemplate and then have all the controls (Label and DropDown in your case) inside that. Each would be toggled based on Grid.EditIndex > -1.
I would start by commenting out parts of the grid (like that whole piece with ObjectDataSource inside an EditTemplate) and see if that works.
If that dropdown / field is the culprit, then I'd re-work it to be populated inside Grid_ItemDataBound() event instead of inside markup.
One possible solution would be to enable the viewstate to false as so:
EnableViewState="false"
The links below will be of some help.
http://forums.asp.net/t/1159585.aspx/1
http://forums.asp.net/t/1295517.aspx/1