I have a gridview which binds data on page load:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindCustomerData();
}
}
I would like to display different buttons depending on the criteria. For simplicity
If its the first gridview row then display "First Record"
If its the last gridview row then display "Last Record"
Any other row "Middle Record"
All buttons start with Visible = False on the markup.
In my RowDataBound event i have
protected void gvCusts_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
int lastIndex = gvCusts.Rows.Count -1;
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button buttonFirst = (Button)e.Row.FindControl("buttonFirst");
Button buttonMiddle = (Button)e.Row.FindControl("buttonMiddle");
Button buttonLast = (Button)e.Row.FindControl("buttonLast");
// Customer Records found
if (c.Id > 0)
{
if (e.Row.RowIndex == 0)
{
// First row so display first button only
buttonFirst.Visible = true;
}
else if (e.Row.RowIndex >= 1 && e.Row.RowIndex <= lastIndex)
{
// Not the first row and not the last row so display the middle button only
buttonMiddle.Visible = true;
}
else if (e.Row.RowIndex == lastIndex)
{
// Last row, so display the last button only.
buttonLast.Visible = true;
}
}
}
}
The problem is i cant find a proper way to get the middle and last rows and have buttons showing at the wrong stages.
I then made the int lastIndex = gvCusts.Rows.Count -1; line of code static and still not getting the correct results.
I've read a number of articles so obviously i'm missing something somewhere but not sure what?
Declare a static variable rowCount in your class.
int rowCount=0;
In your BindCustomerData() method, pass the number of rows to rowCount variable.
rowCount= YourDataTable.Rows.Count-1;
Now, get first and last index from rowCount Variable.
protected void gvCusts_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
int lastIndex = rowCount;//rowCount has the last index
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button buttonFirst = (Button)e.Row.FindControl("buttonFirst");
Button buttonMiddle = (Button)e.Row.FindControl("buttonMiddle");
Button buttonLast = (Button)e.Row.FindControl("buttonLast");
// Customer Records found
if (c.Id > 0)
{
if (e.Row.RowIndex == 0)
{
// First row so display first button only
buttonFirst.Visible = true;
}
else if (e.Row.RowIndex >= 1 && e.Row.RowIndex < rowCount)
{
// Not the first row and not the last row so display the middle button only
buttonMiddle.Visible = true;
}
else if (e.Row.RowIndex == rowCount)
{
// Last row, so display the last button only.
buttonLast.Visible = true;
}
}
}
}
Related
How to set focus to the absolute last row?
I tried all the solutions I found in StackOverflow, but it always goes to the Row before the last, not the last one.
when I edit a value in the Quantity Column and press enter, I add two rows: the colored one which is read-only and also another row where I can add the next item.
Now, when I press Enter after typing the quantity, the focus goes to second row quantity: I need it to go to the first Column (Barcode) of the last row.
private void onCellEditEnd(object sender, DataGridViewCellEventArgs e)
{
if(header == barcode)
{
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value = item.Qty;
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[2].Value = item.Item;
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[3].Value = item.Mrp;
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[4].Value = item.Discount;
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[5].Value = item.Cgst;
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[6].Value = item.Sgst;
dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[7].Value = item.Amount;
dataGridView1.Rows.Add();
dataGridView1.Rows[dataGridView1.CurrentRow.Index+1].Cells[1].Value = item.Details;
dataGridView1.Rows[dataGridView1.CurrentRow.Index+1].Cells[4].Value = item.Discount;
dataGridView1.Rows[dataGridView1.CurrentRow.Index+1].Cells[5].Value = item.Cgst;
dataGridView1.Rows[dataGridView1.CurrentRow.Index+1].Cells[6].Value = item.Sgst;
dataGridView1.Rows[dataGridView1.CurrentRow.Index + 1].ReadOnly = true;
dataGridView1.Rows.Add();
}
dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[2];
}
else if(header == quantity)
{
dataGrid.CurrentCell = dataGrid.Rows[2].Cell[0]; //tried this
dataGridView1.Rows[dataGridView1.RowCount - 1].Selected = true; //tried this
}
}
The second row is part of the first row, so on the CellEndEdit of Quantity I want the focus to go to the 3rd Row, in the Barcode Column, which I have added in the last line of code, using dataGridView1.Rows.Add();
To select a specific row you must use
dataGrid.Rows[index].Selected = true;
Wherever you make a change and you want the last row to be selected, you must use the following code :
dataGrid.Rows[dataGrid.RowCount - 1].Selected = true;
I had the same problem as you a couple weeks ago this is what I did.
private void gridControl1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
int indexOfRecent = gridView1.DataRowCount - 1;
gridView1.FocusedRowHandle = indexOfRecent;
}
}
I got stuck while using the CustomColumnDisplayText Event. I am using this code:
private void gridView1_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e)
{
if (e.Column == colVehicle_FahrzeugartID && e.ListSourceRowIndex >= 0)
{
for (int i = 0; i < gridViewList.DataRowCount; i++)
{
object cellValue = gridViewList.GetRowCellValue(i, "Vehicle_FahrzeugartID");
this.clsFahrzeugart.ReadFromDb((int)cellValue);
if (this.clsFahrzeugart.Systemstatus == 11 && e.ListSourceRowIndex == i)
{
e.DisplayText = "Deleted...";
}
}
}
}
to display deleted if the value Systemstatus is 11 which stands for deleted in my database and everything works fine but if I am toggling my switch there are empty values in my column and some values are getting changed to deleted although they dont have the value 11.
This is how it looks if the Switch is toggled:
And this is how it should look like:
bool isOn = toggleSwitch1.EditValue is bool ? (bool)toggleSwitch1.EditValue : false;
if (isOn)
{
tbAutoBindingSource1.Filter = "Vehicle_Systemstatus = 1";
btn_UnDel.Visible = false;
}
else
{
tbAutoBindingSource1.Filter = "Vehicle_Systemstatus IS NOT NULL";
btn_UnDel.Visible = true;
}
Does somebody know how to fix this?
You do not need to traverse through all rows since this event is raised for an individual row. Since this event provides the e.ListDataSourceRowIndex property associated with a datasource row index, not a row handle, you need to use the GridView.GetListSourceRowCellValue method to access a cell value.
Refer to the Rows help topic to learn differences between datasource indexes and grid row handles.
private void gridView1_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e)
{
GridView view = sender as GridView;
if (e.Column == colVehicle_FahrzeugartID && e.ListSourceRowIndex >= 0)
{
object cellValue = view.GetListSourceRowCellValue(e.ListSourceRowIndex, "Vehicle_FahrzeugartID");
this.clsFahrzeugart.ReadFromDb((int)cellValue);
if (this.clsFahrzeugart.Systemstatus == 11)
e.DisplayText = "Deleted...";
}
}
You have several mistakes in your code.
0. Pointless cycle in event.
The CustomColumnDisplayText event are used to display text in currently processed cell. So, all you need is to get values according to that cell.
1. Wrong using of GetRowCellValue method.
You need to use RowHandle for GetRowCellValue. ListSourceRowIndex is wrong here. RowHandle and ListSourceRowIndex are not the same. You need to use GetRowHandle method to get RowHandle from ListSourceRowIndex.
Here is example:
private void gridView1_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e)
{
if (e.Column == colVehicle_FahrzeugartID && e.ListSourceRowIndex >= 0)
{
int rowHandle = gridViewList.GetRowHandle(e.ListSourceRowIndex);
object cellValue = gridViewList.GetRowCellValue(rowHandle, "Vehicle_FahrzeugartID");
this.clsFahrzeugart.ReadFromDb((int)cellValue);
if (this.clsFahrzeugart.Systemstatus == 11)
{
e.DisplayText = "Deleted...";
}
}
}
I open a CSV File in my DataGridView. When i click on button "Down" the next row is selected.
Problem: when I open a new CSV and click "Down", automatically the selection jumps to the row number of the last selected number of the old CSV.
Example: I select row 11 and open a new file. Row 1 is selected until I press "Down". Instead of row 2, row 11 is selected.
private void btn_down_Click(object sender, EventArgs e)
{
if (dataGridView1.Rows.Count != 0)
{
selectedRow++;
if (selectedRow > dataGridView1.RowCount - 1)
{
selectedRow = 0;
port.Write("...");
}
dataGridView1.Rows[selectedRow].Selected = true;
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.SelectedRows[0].Index;
}
}
You should not use an internal counter to store the selected row since the selection could be changed by other components (in your case by changing the data source). Just make use of the dataGridView1.SelectedRows to get the currently selected row. Based on this row select the next one. Here is a simple implementation:
private void btn_down_Click(object sender, EventArgs e)
{
//Make sure only one row is selected
if (dataGridView1.SelectedRows.Count == 1)
{
//Get the index of the currently selected row
int selectedIndex = dataGridView1.Rows.IndexOf(dataGridView1.SelectedRows[0]);
//Increase the index and select the next row if available
selectedIndex++;
if (selectedIndex < dataGridView1.Rows.Count)
{
dataGridView1.SelectedRows[0].Selected = false;
dataGridView1.Rows[selectedIndex].Selected = true;
}
}
}
I have a gridview where I format a specific number of cells for specific rows:
protected void hoursReportGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.RowIndex == 1 || e.Row.RowIndex == 2)
{
for (int i = 0; i < 14; i++)
{
e.Row.Cells[i].ForeColor = Color.Black;
e.Row.Cells[i].BackColor = ColorTranslator.FromHtml("#EAFDB3");
e.Row.Cells[i].Font.Bold = true;
}
}
}
}
Right now, the rows that get changed are static (row 1 and 2).
I've added functionality to the gridview and now need a dynamic number of rows formatted (between 2 and 10). The rows will always be next to eachother.
How can choose the rows dynamically?
I have a ListBox with number of items matching the number of rows in the GridView. Using this ListBox I want to display a tooltip for each row only to the first column data in the GridView. I have bound the GridView in the front end.
The code I have tried is giving Index of out range error :
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i <= GridView1.Rows.Count; i++)
{
String ProCol = GridView1.Rows[i].Cells[0].ToString();
if (ProCol.Length != 0)
{
e.Row.Cells[0].ToolTip = ListBox1.Items[i].ToString().Trim();
}
}
}
}
It fails in the last iteration of your for cycle, since the index is zero based (first item has 0 index, last item has count-1 index). Replace
i <= GridView1.Rows.Count
with
i < GridView1.Rows.Count
Try moving your code to the DataBound event on the GridView instead of doing the work in RowDataBound. That way, it will only run once when all the rows have been bound and the GridView.Rows collection has been initialized.
Also, you should do what Michal Klouda wrote in his answer regarding <= an <.
And you must make sure that the ListBox1 has been databound before you bind the GridView.
Sample code that should work as long as you bind the ListBox befor the GridView:
protected void GridView1_DataBound(object sender, EventArgs e)
{
var gv = (GridView)sender;
for (int i = 0; i < gv.Rows.Count; i++)
{
var oneRow = gv.Rows[i];
String ProCol = oneRow.Cells[0].ToString();
if (ProCol.Length != 0)
{
oneRow.Cells[0].ToolTip = ListBox1.Items[i].ToString().Trim();
}
}
}