I have following code to remove the summary row/band value on a retrieve UI event. I'm certain this is the wrong way to do it but it works.
public UiEventResult AfterRetrieveData_111(object sender, RetrieveDataEventArgs e)
{
UltraGridBase baseGrid = _view.ViewGrids["ultraGrid1"];
UltraGridLayout gridLayout = baseGrid.DisplayLayout;
for (int i = 0; i < 2; i++)
{
gridLayout.Bands[i].Columns["columnA"].Formula = "''";
}
for (int i = 0; i < 3; i++)
{
gridLayout.Bands[i].Columns["columnB"].Formula = "''";
gridLayout.Bands[i].Columns["columnC"].Formula = "''";
}
Is there a way to program the retrieve so that it populates the summary row for column A/band[2] so that is uses the last value in each column? Without the above code it will sum rows under but would like for a way for it to use the last row value instead. Data will always be sorted DESC by date so last row will always be the value needed...
One way to achieve this is in InitializeRowEvent by setting the value of the columnA to the value of the last row in the child band like this:
// Update the rows only in the first band. You can also use e.Row.Band.Key == {YOU_BAND_KEY}
if (e.Row.Band.Index == 0)
{
// set the value of the columnA to the value of the last row in the child band
e.Row.Cells["columnA"].Value = e.Row.ChildBands.LastRow.Cells["columnA"].Value;
}
Note, this will not work if you edit the cells values. If you need to update the parent row value after cell update, again in InitializeRowEvent you can add this:
// look for row in the secon band
if (e.Row.Band.Index == 1)
{
// get the last row in the second band
if (e.Row == e.Row.ParentRow.ChildBands.LastRow)
{
// get the value of the last row in the second band and set it to the parent row
e.Row.ParentRow.Cells["columnA"].Value = e.Row.Cells["columnA"].Value;
}
}
This will loop through ChildBands and set parent row value with the last value in each ChildBand.
int rowCount = gridLayout.Rows.Count;
for (int i = 0; i < rowCount; i++)
{
foreach (UltraGridChildBand childBand in baseGrid.Rows[i].ChildBands)
{
foreach (UltraGridRow row in childBand.Rows)
{
row.Cells["columnA"].Value =row.ChildBands.LastRow.Cells["columnA"].Value;
}
}
}
Related
I have a function that sets column values for all rows:
The code that sets this:
//Update the engineers for all rows
Btn_ValidateClick_ItemClick(object sender,ItemClickEventArgs e)
{
UpdateTotalTime(gridView);
}
private void UpdateEngineers(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
//Column name that need to be updated (set)
DevExpress.XtraGrid.Columns.GridColumn col = View.Columns.ColumnByFieldName("Engineers");
try
{
int dataRowCount = View.DataRowCount;
for (int i = 0; i < dataRowCount; i++)
{
GridView detail = (GridView)gridView.GetDetailView(i, 0);
string language = gridView.GetRowCellValue(i, "Language").ToString();
for (int y = 0; y < gridView.GetDetailView(i, 0).RowCount; y++)
{
//Add all values found in a detail column to an arraylist
values.Add(detail.GetRowCellValue(y, "EngineerInitials").ToString());
}
if (values.Count >0 )
object t = //string join ...
View.SetRowCellValue(i, col, t);
}
else
{
object t = "No engineers"
View.SetRowCellValue(i, col, t);
}
}
}
}
}
The problem is that now, I want it only to set it for the rows that are selected.
I tried using the .GetSelectedRows()-function and adding the rows to an ArrayList, but this doesn't allow customability really:
private void UpdateTotalTime(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
ArrayList selectedRows = new ArrayList();
for (int i = 0; i < gridView.SelectedRowsCount; i++)
{
if (gridView.GetSelectedRows()[i] >= 0)
selectedRows.Add(gridView.GetDataRow(gridView.GetSelectedRows()[i]));
}
try
{
int count = View.GetSelectedRows().Count();
for (int i = 0; i < selectedRows.Count; i++)
{
//This gets the first row of the count, not the first selected row
GridView detail = (GridView)gridView.GetDetailView(i,0);
}
}
If I select the 3 bottom rows, the first 3 get updated. Why is this?
You are adding all the selected rows to your selectedRows ArrayList. But after that, you are not using it for anything.
I guess what you want (I've never used devexpress controls) is using those selectedrows RowHandle to pass it to the GetDetailView method. According to the GetSelectedRows documentation, the method returns the int handles of the selected rows, so your code should look like this:
First, you must save the DataRow handles, not the DataRow itself, so you must change in your code this line:
selectedRows.Add(gridView.GetDataRow(gridView.GetSelectedRows()[i]));
into this:
selectedRows.Add(gridView.GetSelectedRows()[i]);
And then, change your loop into this:
for (int i = 0; i < selectedRows.Count; i++)
{
int rowHandle = (int)selectedRows[i];
GridView detail = (GridView)gridView.GetDetailView(rowHandle,0);
}
In fact, you could do everything in just one loop:
private void UpdateTotalTime(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
for (int i = 0; i < gridView.SelectedRowsCount; i++)
{
int rowHandle = gridView.GetSelectedRows()[i];
GridView detail = (GridView)gridView.GetDetailView(rowHandle,0);
}
}
I want to select column from data grid view.
Then, I want to add data in cells number 5 for the selected column.
Below code is not worked.
for (int i = 0; i < dgvSRP.Rows.Count; ++i)
{
dgvSRP.Rows.Add();
DataGridViewRow row = this.dgvSRP.Rows[i];
row.Cells[5].Value =txtJumlahPEsanan.Text;
}
foreach(var dgvRow in dgvSRP.Rows)
{
dgvRow.Cells[4].Value = txtJumlahPEsanan.Text; // The 5th column is index 4. Indexes always start at 0.
}
Here is my code i have select specific column value and assign it to textbox. May this solve your problem. Remember i have two cells rows thats why i kept cell[1] because index start from 0.
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (i == 5)
{
textBox3.Text = dataGridView1.Rows[i].Cells[1].Value.ToString();
}
}
I have a Column that looks like this:
Column 3:
-1
-2
-2a
-2b
etc...
try
{
int count = 0; int GetLength; string Result;
for (int i = 0; i < MMDetailsList.Items.Count; i++)
{
if (!string.IsNullOrEmpty(MMDetailsList.Items[count].SubItems[3].Text))
{
GetLength = MMDetailsList.Items[count].SubItems[3].Text.Length;
Result = Convert.ToString(MMDetailsList.Items[count].SubItems[3].Text[GetLength]);
MessageBox.Show(Result);
//getCategoryNum = MMDetailsList.Items[count].SubItems[3].Text;
}
count++;
}
}
catch (Exception) { }
What i'm doing is i wanted to know that if my series has a character at the end so i can increment it each time a button is clicked let say 2a if there's a character at its last value increment it to b and if b is deleted in row it would check again the last entry in the row a and would increament it back to b instead its c i need to check it 1st if it exist in my code i tried to check the last value of the column but it doesn't show my question is how do i check the last part character of the value inside the column listview i tried doing it with the code above but it's doesn't show a messagebox either.
for (int i = 0; i < MMDetailsList.Items.Count; i++)
{
string text = MMDetailsList.Items[i].SubItems[3].Text;
if (!string.IsNullOrEmpty(text))
{
if(char.IsLetter(text.Last()))
{
MessageBox.Show("Last Letter :" +text.Last());
}
}
}
I have a simple function in my program that selects the current cell, then it (FillsDown) copies the current cell into ALL the cells below it.
However my simple function places the value in the Row at the bottom which is the new row and I do not want the value to be populated here.
Heres the current code. (Where COLINDEX is just the column im referring to in my grid)
string replacestring = row.Cells[COLINDEX].Value.ToString();
foreach (DataGridViewRow row in dataGrid1.Rows)
{
if (row.Index > startrow)
{
row.Cells[COLINDEX].Value = replacestring;
}
}
Is there a simeple method/property I can check against so I dont accidently populate the last row ?
My example below uses a fake property (.Exist)
foreach (DataGridViewRow row in dataGrid1.Rows)
{
if ((row.Index > startrow) && row.Exist)
{
row.Cells[COLINDEX].Value = replacestring;
}
}
DataGridViewRow has a property called IsNewRow
And try to walk the Rows collection using the index
for(int x = startRow + 1; x < dataGrid1.Rows.Count; x++)
{
DataGridViewRow row = dataGrid1.Rows[x];
if (row.IsNewRow == false)
{
row.Cells[COLINDEX].Value = replacestring;
}
}
I have datagridview on my winform. I am displaying records in the datagridview. Now after displaying the records on the datagridview, I want to remove the row from datagridview which has one or more empy cells that is no value in the cell for that row. So for that I am checking each cell for every row if there is any cell empty or null then I remove that rows using RemoveAt() function.
My code is :
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
if (string.IsNullOrEmpty(dataGridView1.Rows[i].Cells[j].Value.ToString()))
{
dataGridView1.Rows.RemoveAt(i);
break;
}
}
}
Then problem is it does not work properly that it does not remove all the rows which has empty cell. So what should I do here ?
The simplest way to do what you want is to loop through the datagridview rows in reverse. This way your indices stay correct.
for (int i = dataGridView1.Rows.Count -1; i >= 0; i--)
{
DataGridViewRow dataGridViewRow = dataGridView1.Rows[i];
foreach (DataGridViewCell cell in dataGridViewRow.Cells)
{
string val = cell.Value as string;
if (string.IsNullOrEmpty(val))
{
if (!dataGridViewRow.IsNewRow)
{
dataGridView1.Rows.Remove(dataGridViewRow);
break;
}
}
}
}
I'm doing a couple of extra things that you may not need to do (the code is just cut and pasted from my test application)
I usually grab the row in question into a DataGridViewRow object.
I am checking the IsNewRow property because my grid was editable.
I am assigning the value to a string variable (with an as to cast it) since the way you had it was throwing an exception for me.