oldvalues of SqlDatasource for dynamic gridview-templates - c#

For a dynamic Gridview i am generating columns at runtime like this:
TemplateField tf = new TemplateField();
tf.HeaderText = colName;
tf.ItemTemplate = new GenericItem(ListItemType.Item, colName, "Command");
tf.EditItemTemplate = new GenericItem(ListItemType.EditItem,
Gridview1.Columns.Add(tf);
The GenericItem implements IBindableTemplate:
public class GenericItem : IBindableTemplate
This works fine, but when i am trying to update some columns, i need to have access to the old values. I assumed i could just use this:
<asp:SqlDataSource runat="server" ID="dsGridview" OldValuesParameterFormatString="old_{0}" ConflictDetection="CompareAllValues" />
But when i want to access the oldvalues property of my datasource in the RowUpdating event of the Gridview i noticed that the oldvalues collection is empty (the newvalues collection is filled just fine)
Does anybody know how i can get those oldvalues?
Best regards,
r3try

ok, this is not how i wanted to solve it - but as there are no other suggestions here is how i worked around my problem. Maybe someone else has the same problem:
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//GET THE OLD VALUES
myOldValues.Clear();
GridView gv = (GridView)sender;
gv.EditIndex = e.NewEditIndex;
gv.DataBind();
//populate
for (int i = 0; i < Gridview1.Columns.Count; i++)
{
DataControlFieldCell cell = gv.Rows[e.NewEditIndex].Cells[i] as DataControlFieldCell;
gv.Columns[i].ExtractValuesFromCell(myOldValues, cell, DataControlRowState.Edit, true);
}
Session["MyOldValues"] = myOldValues;
}

Related

DevExpress lookupedit repository item add new row in Xtra Grid View in first row

I have a devexpress gridcontrol with 5 columns. The first column is a lookupedit repository with some data, let say with CarTypes.
To load data in grid I am using a BindingSource. In this BindingSource.DataSource I have load a IList<Cars>
and then
added this binding source in dataSource of my gridcontrol
like bellow
BindingSource _carsBindingSource = new BindingSource();
private void BindData(IList<Cars> data)
{
_carsBindingSource.DataSource = data;
carsGridControl.BeginUpdate();
carsGridControl.DataSource = _carsBindingSource;
carsGridControl.RefreshDataSource();
carsGridControl.EndUpdate();
}
I have a button to add new line in my grid "Add new car" and add a new line in _carBindingSource
private void AddNewRow()
{
_newRow = true;
_carsBindingSource.AllowNew = true;
Cars newCar = new Cars();
newCar.CarType = new CarType();
_carsBindingSource.Add(newCar );
//_carsBindingSource.Insert(0,newCar);
}
Now I want to add the new line in the first row of grid.
I use Insert
_carsBindingSource.Insert(0,newCar);
But it didn't work. The lookupedit repository can't load data.
With _carsBindingSource.Add(newCar); it works fine
Can anyone help me? Thank you!
If you haven't already, consider using an intermediate list for your car types:
private List<CarTypes> _CarTypes;
// Elsewhere in the code...
_CarTypes = GetCarTypes();
And then in the form load event, be sure this is bound to the data source:
repositoryLookupItemCarTypes.DataSource = _CarTypes;
With this, the grid should now automatically manage the instantiation and selection of the CarType object for each Cars object. You can omit this line when you add a car to the grid:
newCar.CarType = new CarType();
In the designer, I think it helps to alter the DisplayMember Property of the repository Item.
With this setup, any Car added to your grid should automatically have the CarType as a populated Lookup Edit.
If any of this is unclear, let me know. I did a quick and dirty solution to test this, and I obviously can't post it all, but I can tell you it did work with both Add and Insert.
Actualy I found a solutions.
The problem was in GridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) event
where I change the AllowEdit value (e.Column.OptionsColumn.AllowEdit = true;).
private void gridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
string cName = e.Column.FieldName;
GridView gv = sender as GridView;
if (cName == "CarType.IdApi")
{
if (isNewRow)
{
Cars cars= (Cars)gv.GetRow(e.RowHandle);
int a = e.RowHandle;
if (cars.ID== 0 && e.RowHandle == 0)
{
e.Column.OptionsColumn.AllowEdit = true;
}
else
{
e.Column.OptionsColumn.AllowEdit = false;
}
}
}
}
When I use Insert(0, new Car) then because of second row whitch has value
the AllowEdit was false;
So I remove else code and it works
private void gridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
string cName = e.Column.FieldName;
GridView gv = sender as GridView;
if (cName == "CarType.IdApi")
{
if (isNewRow)
{
Cars cars= (Cars)gv.GetRow(e.RowHandle);
int a = e.RowHandle;
if (cars.ID== 0 && e.RowHandle == 0)
{
e.Column.OptionsColumn.AllowEdit = true;
}
}
}
}
So finlay I found that bindingSource.Add(object) and bindingSource.Insert(0,object) is same!
I apologize for my english!!

FindControl not finding the correct control in GridView

I have an issue with a GridView and a HiddenField inside the GridView. I'm trying to pull some data based in the value of the HiddenField which is basically the row_id for each record but for some reason I keep getting the same data regardless of which one I select in the GridView. The code below is the one I'm using the find the HiddenField in the GridView.
Any help will be greatly appreciated it.
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
foreach (GridViewRow item in GridView1.Rows)
{
if (item.RowType == DataControlRowType.DataRow)
{
rowid = (HiddenField)(item.Cells[0].FindControl("po_id_hf"));
}
}
GridView2.DataSource = View_SP.v_asn_detail_by_asn_number(Int32.Parse(rowid.Value));
GridView2.DataBind();
step2.Visible = false;
step3.Visible = true;
}
What about using:
GridView1.Rows[e.RowIndex]
to get the current updating row?
EDIT: Your code will always return the last GridViewRows, since it is iterating through the whole GridViewRows collection so at the end rowid will have the last row id in the gridview.
I was over thinking this, below is the solutions:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
string row_id = (((HiddenField)(GridView1.Rows[e.RowIndex].FindControl("po_id_hf"))).Value);
GridView2.DataSource = View_SP.v_asn_detail_by_asn_number(Int32.Parse(row_id));
GridView2.DataBind();
step2.Visible = false;
step3.Visible = true;
}
Thank you guys.

GridView edit when bound to a Datatable

I am creating a website where our customers can order parts directly from us. I have a datatable setup and when users click a button it adds a quick detail of the order to a gridview. In the gridview, I have the edit and delete buttons enabled. the delete function works fine, however when you try to edit the information, it doesn't change the gridview with the new info. Here's what I have so far:
protected void griditems_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
DataTable dt = (DataTable)Session["table"];
foreach (DataRow dr in dt.Rows)
{
part = Convert.ToString(dr["Part"]);
dr["Part"] = part;
dr["Quantity"] = qty;
dr["Ship-To"] = shipto;
}
griditems.EditIndex = -1;
BindData();
}
when trying this, it displays the gridview back with the original input values. I have also tried this (not working and get an error that says "There is no row at position 0":
DataTable dt = (DataTable)Session["table"];
GridViewRow row = griditems.Rows[e.RowIndex];
dt.Rows[row.DataItemIndex]["Part"] = ((TextBox)(row.Cells[1].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["Quantity"] = ((TextBox)(row.Cells[2].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["Ship-To"] = ((CheckBox)(row.Cells[3].Controls[0])).Checked;
griditems.EditIndex = -1;
BindData();
Am I missing an EditItemTemplate in the aspx file, or am I just doing the RowUpdating all wrong?
You probably need to step back a bit and first check out how you could do create, update, delete and read with a grid view. Also, you may wanna check this post.

ASP.Net: Getting DataKey from GridView on Edit and Delete

I am using a GridView control which is databound to a List of objects returned from a utility method. The GridView control has one of the columns set as its DataKey. When a row is Selected, it fires the Selected event handler and I can use myGridView.SelectedDataKey.Value to get the value of the DataKey column for the selected row.
However, the event handler for when a row is Edited or Deleted does not seem to have a mechanism to get the DataKey value for the row in question. The event arg parameter for these event handlers contains the index of the row in the GridView but I'm specifically after the DataKey value.
Re-obtaining the List of objects via the utility method along with the index obtained from the event arg parameter is not an option because the List of objects may have changed.
Can anyone tell me how I can do this?
TIA
protected void gridQuestion_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int id = (int)grdQuestions.DataKeys[e.RowIndex].Value;
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
int i;
Con.Open();
cmd = new SqlCommand("USP_REGISTER", Con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#P_CH_ACTION_CODE", "D");
for ( i = 0; i <= grdApplication.Rows.Count - 1; i++)
{
CheckBox Ck=grdApplication.Rows[i].FindControl("cbItem") as CheckBox;
if (Ck.Checked==true)
{
int Id = (int)grdApplication.DataKeys[i].Values["INT_ID"];
cmd.Parameters.AddWithValue("#P_INT_ID", Id);
SqlParameter StrOut = new SqlParameter();
StrOut = cmd.Parameters.AddWithValue("#P_MSG_OUT", "out");
StrOut.Direction = System.Data.ParameterDirection.Output;
cmd.ExecuteNonQuery();
StrRetVal = (string)cmd.Parameters["#P_MSG_OUT"].Value;
}
Con.Close();
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
here's my solution:
in the gridview set the DataKeyNames="id". this way the row will have a datakey
then in Grd_RowDataBound add an attribute to the button like this:
LinkButton Btn= (LinkButton)e.Row.FindControl("BtnDelete");
if (Btn!= null)
{
Btn.Attributes.Add("ROW_INDEX", e.Row.RowIndex.ToString());
}
then in the OnClick event use this:
int rowIndex= Convert.ToInt32(((LinkButton)sender).Attributes["ROW_INDEX"].ToString());
int id= Convert.ToInt32(Grd.DataKeys[rowIndex].Value);
and you got the datakey value in the gridview's postbacks.
You could use the index number returned from the Edit/Delete event and then select the row manualy
String yourDataKey = GridView.DataKeys[e.NewSelectedIndex].Item["youfield"].tostring();

How to Set a gridview column width when binding to a datatable

I am binding a table to a gridview in asp.net as such
grdIssues.DataSource = mdtIssues;
grdIssues.DataBind();
The problem is I cannot then control the column width, asp.net seems to decided on it's own what width each column should be. Methods such as
grdIssues.Columns[0].ItemStyle.Width = 100;
grdIssues.Columns[1].ItemStyle.Width = 100;
don't work because the columns are created dynamically. I cannot believe there isn't a way to do this short of manually creating each column and filling each row.
You dont have to manually create the columns to set them the width, you can do this
foreach (DataControlField column in OrdersGV.Columns)
{
column.ItemStyle.Width = Unit.Pixel(100);
}
I was able to change the width of a certain Gridview column (bound to a Datatable) with the RowDataBound event:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
e.Row.Cells[0].Attributes["width"] = "200px";
}
I like to answer my own question whenever I can so future users searching the thread will find the answer.
I could not find a way to do what I wanted directly. However I found if I define the columns myself, I could change the properties. In this example, I wanted to center the column data. Something like this.
BoundField bdfRaisedDate = new BoundField();
clsUtilities.SetBoundFieldCenter(ref bdfRaisedDate, "RaisedDateShort", "Opened", "RaisedDate");
grdIssues.Columns.Add(bdfRaisedDate);
grdIssues.DataSource = mdtIssues;
grdIssues.DataBind();
public static void SetBoundFieldCenter(ref BoundField bdfAny, string pDataField, string pHeadingValue, string pSortExpression)
{
bdfAny.DataField = pDataField;
bdfAny.HeaderText = pHeadingValue;
bdfAny.SortExpression = pSortExpression;
bdfAny.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
bdfAny.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
}
I did it as:
gridView1.HeaderRow.Cells[0].Attributes["Width"] = "100px";
gridView1.HeaderRow.Cells[1].Attributes["Width"] = "50px";
gridView1.HeaderRow.Cells[2].Attributes["Width"] = "200px";
I'd do it like this:
foreach (DataControlField field in grdIssues.Columns)
{
field.HeaderStyle.Width = 100;
}

Categories