ASP.NET GridView allow to edit certain row - c#

Is there a way to allow editing of certain row instead of the whole row?
When I search a user it will fill data into the GridView. If I set the AutoGenerateEditButton to True, all the row will be editable. For example, if the GridView has 10 row, when the data in the row is between a certain criteria using If-else statement, I only want the bottom 5 to be editable instead of the whole 10 row.

try this..On gridviews row data bound event check the criteria ..
protected void Gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if ("Your Condition")
{
if ("your condition")
{
e.Row.Enabled = true;//row is editable
}
else
{
e.Row.Enabled = false;//row is not editable
}
}
}

Related

how to get the rows property in gridview of devxpress with a button to edit?

i have a gridview with devexpress my gridview contain a id ID="GriviewLV1" and i have a button in the row of the gridview to edit the record , in the event click of the button im trying give click in the button to edit but cannot get the property rows or something like that. im trying something like this but cannot do rows property because dont exist the rows property in grid view devexpress
button_Edit_click(object sender, EventArgs e)
{
foreach (GridViewRow row in GriviewLV1.Rows)
{
}
}
And for what exactly do you need row collection?
As far as I know, you can only manipulate with records (DataSource property object). Also it is possible to get selected row. Some my code examples with explanation:
private List<ImageSetMember> imageSets;
...
//assign collection as grid's DataSource.
//From now on any actions on imageSets object will be automatically reproduced
//as grid's row changes.
imageSetGridControl.DataSource = imageSets;
...
private void replaceButtonEdit_Click(object sender, System.EventArgs e)
{
//get focused row record's index at DataSource collection
int index = imageSetGridView.GetDataSourceRowIndex(imageSetGridView.FocusedRowHandle);
var selectedImage = imageSet[index].Image; //accessing to row's record
}

How make a DataGridVewLinkColumn sort with the rest of the DataGridView

I populated a DataGridView with a DataTable as DataSource. This DataSource has a column with comments in it. I hide this column as part of the requirements and added a new DataGridVewLinkColumn that when is clicked the user will be able to see that comment.
My problem is when I sort by clicking on any of the headers from the DataGridView, all the DataGridViewLinkColumn links disappear. I have set the SortMode to Automatic in this LinkColumn but seems that I need to do something else because still as soon as I click on the headers from the other columns in the Grid the links disappear.
Any one knows how can I make sure that when the DataGridView is sorted the link column gets sorted accordingly?
Many thanks
OK I figure it out. The problem is because I used a DataTable as DataSource it was binded to the grid and there is no way to add an extra column to a grid source that is already binded and expect that it will bind with the source.
To solve this problem I just modified the data table. Add the extra column in the data table with the strings that will be the links in the DataGridView and populate the DataGridView programatically as recommended in http://msdn.microsoft.com/en-us/library/bxt3k60s(v=vs.90).aspx
Column Sort Modes in the Windows Forms DataGridView Control
When a DataGridView control containing both bound and unbound columns is sorted, the values in the unbound columns cannot be maintained automatically. To maintain these values, you must implement virtual mode by setting the VirtualMode property to true and handling the CellValueNeeded and CellValuePushed events.
This is a bit complicated, so the simplest solution would be to add an extra column into your DataTable.
I'll leave an example below for future reference.
The points are:
VirtualMode should be true.
CellValueNeeded should be handled properly to show the specified cell values.
ColumnHeaderMouseClick should be handled properly to sort by the unbound columns, and to show sort glyphs.
Note:
The DataGridView in this example is read-only to make things simple.
This example form contains:
A typed DataSet, that has DataTable1 with columns of ID(string), Comment(string):
private DataSet1 dataSet1;
A BindingSource:
private BindingSource dataTable1BindingSource;
.DataMember = "DataTable1";
.DataSource = this.dataSet1;
A DataGridView:
private DataGridView dataTable1DataGridView;
.DataSource = this.dataTable1BindingSource;
.VirtualMode = true;
.CellValueNeeded += this.dataTable1DataGridView_CellValueNeeded;
.ColumnHeaderMouseClick += this.dataTable1DataGridView_ColumnHeaderMouseClick;
.ReadOnly = true;
.AllowUserToAddRows = false;
.AllowUserToDeleteRows = false;
Its columns:
private DataGridViewTextBoxColumn iDDataGridViewTextBoxColumn; // bound column
private DataGridViewTextBoxColumn commentDataGridViewTextBoxColumn; // bound column
private DataGridViewLinkColumn linkColumn; // unbound column
.SortMode = DataGridViewColumnSortMode.Automatic;
And here goes the code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Hold the link texts, in a dictinary
// keyed by ID (= unique key in DataTable1), to be bound to each row.
private SortedDictionary<string, string> _linkTexts
= new SortedDictionary<string, string>();
private void Form1_Load(object sender, EventArgs e)
{
// Bound data sample
this.dataSet1.DataTable1.AddDataTable1Row("1", "Comment1");
this.dataSet1.DataTable1.AddDataTable1Row("2", "Comment2");
this.dataSet1.DataTable1.AddDataTable1Row("3", "Comment3");
// Unbound data sample
this._linkTexts.Add("1", "linkA");
this._linkTexts.Add("2", "linkC");
this._linkTexts.Add("3", "linkB");
}
// Handles ColumnHeaderMouseClick to do custom sort.
private void dataTable1DataGridView_ColumnHeaderMouseClick(
object sender, DataGridViewCellMouseEventArgs e)
{
// When the unbound column header is clicked,
if (e.ColumnIndex == this.linkColumn.Index)
{
// Create a new DataView sorted by the link text
// with toggling the sort order.
DataView newView;
switch (this.linkColumn.HeaderCell.SortGlyphDirection)
{
case SortOrder.None:
case SortOrder.Descending:
this.linkColumn.HeaderCell.SortGlyphDirection
= SortOrder.Ascending;
newView = this.dataSet1.DataTable1
.OrderBy(row => this._linkTexts[row.ID])
.AsDataView();
break;
default:
this.linkColumn.HeaderCell.SortGlyphDirection
= SortOrder.Descending;
newView = this.dataSet1.DataTable1
.OrderByDescending(row => this._linkTexts[row.ID])
.AsDataView();
break;
}
// Set it as DataSource.
this.dataTable1BindingSource.DataSource = newView;
// Clear sort glyphs on the other column headers.
foreach (DataGridViewColumn col
in this.dataTable1DataGridView.Columns)
{
if (col != this.linkColumn)
col.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
// The bound column header is clicked,
else
{
// Sorting has done automatically.
// Reset the sort glyph on the unbound column.
this.linkColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
// Handles CellValueNeeded to show cell values in virtual mode.
private void dataTable1DataGridView_CellValueNeeded(
object sender, DataGridViewCellValueEventArgs e)
{
// Extract the bound row from the current data view.
DataSet1.DataTable1Row row
= (this.dataTable1BindingSource[e.RowIndex] as DataRowView)
.Row as DataSet1.DataTable1Row;
// For the unbound column,
if (e.ColumnIndex == this.linkColumn.Index)
{
if (row.IsIDNull())
e.Value = DBNull.Value;
else
// get the value from the dictionary.
e.Value = this._linkTexts[row.ID];
}
// For the bound columns,
else
{
// get the value from the data source.
string propName = this.dataTable1DataGridView
.Columns[e.ColumnIndex].DataPropertyName;
e.Value = row[propName];
}
}
}

Get data from a specific column when pressing edit on that row in GridView

How do I get data from a specific column that the edit button was pressed on in a gridview?
The following code doesnt work:
protected void viewStoryTime_OnRowEditing(object sender, GridViewEditEventArgs e)
{
SqlDataSource10.UpdateParameters["setEditHoursParam"].DefaultValue = viewStoryTime.SelectedRow.Cells[0].Text;
}
This is because the row is not actually selected. How can I accomplish this?
e.NewEditIndex has the row index of the currently-editing row. You can use that to access the row and read the cell data as necessary.
The parameter GridViewEditEventArgs contains the row index for the current edited row from the gridview.
You should do something like this
SqlDataSource10.UpdateParameters["setEditHoursParam"].DefaultValue = MyGridView.Rows[e.NewEditIndex].Cells[0].Text;
Another way could be implement a RowCommand event where parameter GridViewCommandEventArgs carries the command name, then you should do something like this:
void MyGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if(e.CommandName=="my command name")
{
//Do stuff here
}
}

Hiding a GridView ID column

Seems to be a common issue.
I'm trying to hide a column of my GridView. I have read that simply setting the column to 'visible = false' will not work as I'm auto-generating my data.
Currently my code stands as so:
protected void Page_Load(object sender, EventArgs e)
{
bind();
if (GridView1.Columns.Count > 0)
GridView1.Columns[0].Visible = false;
else
{
GridView1.HeaderRow.Cells[0].Visible = false;
foreach (GridViewRow gvr in GridView1.Rows)
{
gvr.Cells[1].Visible = false;
}
}
}
The 'if' statement will not trigger as as said I am auto-generating the data. With the above loop, I can hide the header text of the column but want to hide the whole column with the ability to still be able to access the hidden data.
How about just doing this later in the control's life cycle (when the Columns collection has been populated):
protected void GridView1_PreRender(object sender, EventArgs e)
{
if (GridView1.Columns.Count > 0)
GridView1.Columns[0].Visible = false;
else
{
GridView1.HeaderRow.Cells[0].Visible = false;
foreach (GridViewRow gvr in GridView1.Rows)
{
gvr.Cells[1].Visible = false;
}
}
}
Note: you would need to add OnPreRender="GridView1_PreRender" to your GridView markup.
Why not use the GridView.DataKeyNames and GridView.DataKeys properties to store the ID and then retrieve it with the rowIndex later? This also will keep the column from being autogenerated.
DataKeyNames
DataKeys
This is a limitation with auto-generating columns. You give up a lot of control over HOW the columns are displayed for the convenience of not pre-defining them.
Bite the bullet now and define your columns. If this is the ONLY customization you need to make, you may be all right, but 90+% of the time I end up defining columns to customize how they are displayed.
Otherwise you're going to end up with several of these "tweaks" that are prone to breaking under various circumstances (e.g. the order of the columns changes in the data source).
Ah... so the problem is the Columns is not predefined.
Perhaps you could use Linq to select all the columns you want to display:
gvTest.DataSource = (from d in dataSource
select new
{
ColumnA = d.ColumnA...
}
Alternatively, you could hide the columns with JavaScript;

How to highlight specific row in a DetailsView?

I am a new ASP.NET developer. I am using a DetailsView now to dispaly some data from the database. I have the need to highlight certain two rows from the DetailsView. Both rows are VARCHAR data type.
SO HOW TO DO THAT?
Override the databound event and set the e.Row.BackColor = System.Drawing.Color.Red; or what ever color, if you have some logic to execute for finding the row that needs to be highlighted.
protected void detailsView_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if(...)//some condition for selection of row to be higlighted
{
e.Row.BackColor = System.Drawing.Color.Red;
}
}
}
If you need a perticular row, say 4th row to be highlighted and that's fixed then you could directly like this
detailsViewGrid.Rows[3].Row.BackColor = System.Drawing.Color.Red;
The only thing you need to keep in mind that this code would be written in only those events which would come after grid_rowdatabound event(Like pre-render)

Categories