I have a ListView. My main goal is to be able, to copy the ListViewItems to the Clipboard and then to Excel. But I have troubles to read the ListView Cells.
To get the Columns I use:
var columnNames = new StringBuilder();
foreach (GridViewColumn column in ((GridView)(listViewSolution.View)).Columns)
{
columnNames.Append(column.Header + "\t");
}
Now I want to add the rows, but I'm only able to access the first Cell in the first column, not the second or third..:
var stringBuilder = new StringBuilder();
for (int i = 0; i < listViewSolution.Items.Count; i++)
{
stringBuilder.Append("\n");
//foreach (GridViewColumn column in ((GridView)(listViewSolution.View)).Columns)
//{
//if (column.Header != null)
//{
ListViewItem myListBoxItem =
(ListViewItem)(listViewSolution.ItemContainerGenerator.ContainerFromIndex(0)); //= Index 0 -> First Row, First Cell; Index 1 = Second Row, First Cell; But do we get: Second Column, First Row????
stringBuilder.Append(myListBoxItem.Content.ToString() + "\t");
//}
//}
}
System.Windows.Clipboard.SetData(DataFormats.Text, columnNames.ToString() + stringBuilder.ToString());
Help would be much appreciated..
You're not changing the index in the .ContainerFromIndex call each iteration. Use your loop variable there and see what you get.
Related
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;
}
}
}
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 method that stores each line in a gridview into the database, then if the save is successful, removes the row; but if it isn't successful (cannot be stored in the db) it does not remove the row. Unfortunately, I can't get the row-removal to work properly.
This is my current code:
public static void SavePAC(PlantAreaCode_CreateView CView)
{
List<int> removeRows = new List<int>();
// For each cell in the DataGrid, stores the information in a string.
for (rows = 0; rows < CView.dataGridView1.Rows.Count; rows++)
{
correctSave = false;
if (CView.dataGridView1.Rows[rows].Cells[col].Value != null)
{
// Creates a model, then populates each field from the cells in the table.
PModel = new PlantAreaCode_Model();
PModel.AreaCode = Convert.ToString(CView.dataGridView1.Rows[rows].Cells[0].Value);
PModel.AreaName = Convert.ToString(CView.dataGridView1.Rows[rows].Cells[1].Value);
PModel.Comments = Convert.ToString(CView.dataGridView1.Rows[rows].Cells[2].Value);
// Passes the model into the Database.
Database_Facade.Operation_Switch(OPWRITE);
}
if (correctSave == true) // correctSave is set in the database insert method.
{
removeRows.Add(rows);
}
}
foreach (int i in removeRows)
{
CView.dataGridView1.Rows.RemoveAt(0); // Deletes all bar the last row, including any rows that cause errors
}
}
I have also tried:
foreach (int i in removeRows)
{
CView.dataGridView1.Rows.RemoveAt(i);
}
But that crashes at halfway, because the Rows index keeps changing each time a row is removed.
How can I achieve this? How can I remove a row if the save is successful, but keep it if there is an error?
May this help:
1] Make sure correctSave is being modified correctly.
2] Revert the loop flow, Looping backward allow to remove the row processed by the loop without affecting the index of the next row to process.
for (rows = CView.dgvCreate.Rows.Count - 1; rows >= 0 ; rows--)
3] Use CView.dataGridView1.Rows.RemoveAt(rows);
Try to populate collection of rows for removing with DataGridViewRow not with index. This works for me.
public void SavePAC(PlantAreaCode_CreateView CView)
{
List<DataGridViewRow> removeRows = new List<DataGridViewRow>();
foreach (DataGridViewRow row in CView.dataGridView1.Rows)
{
correctSave = false;
if (row.Cells[col].Value != null)
{
// Creates a model, then populates each field from the cells in the table.
PModel = new PlantAreaCode_Model();
PModel.AreaCode = Convert.ToString(row.Cells[0].Value);
PModel.AreaName = Convert.ToString(row.Cells[1].Value);
PModel.Comments = Convert.ToString(row.Cells[2].Value);
// Passes the model into the Database.
Database_Facade.Operation_Switch(OPWRITE);
}
if (correctSave == true) // correctSave is set in the database insert method.
{
removeRows.Add(row);
}
}
foreach (DataGridViewRow rowToRemove in removeRows)
{
CView.dataGridView1.Rows.Remove(rowToRemove);
}
}
You have to sort removeRows in descending order.
List<int> removeRowsDesc = removeRows.OrderByDescending(i => i);
Then use the foreach loop
foreach (int i in removeRowsDesc)
{
CView.dataGridView1.Rows.RemoveAt(i);
}
This way the reindexing wont affect the deletion.
I have a problem.
I have two loops (one for row, one for column) for creating data in DataTable. I want to check if cell is empty for column named "Name" and if it is empty just don't add this row. And here is a question: How to cancel adding row?
Got some code:
for (int i = 0; i < data.Count(); i++)
{
cell = data.ElementAt(i);
DataRow row;
row = dataTable.NewRow();
foreach (string column in columns)
{
if (row["Name"] == "")
{
row = null;
}
else
{
row[column] = cell;
}
}
if (row != null)
{
dataTable.Rows.Add(row);
}
}
But after next loop is starting it throws NullException: Object reference not set to an instance of an object.
Generally I want to add Rows to DataTable only those where value of cell is not empty at column called "Name" (i mean where is "").
What is the best way or easiest way to do it right?
Change it as:
....
foreach (string column in columns)
{
if (row["Name"] == "")
{
row = null;
break; //--> Add this line
}
else
{
row[column] = cell;
}
}
....
This seems like it would be easy but I can't find a way to retrieve the text from the selected row on a DataGrid. The grid is single row selected only - no multiple row selection is allowed.
Figured it out. One way is
string val = (string)dataGrid1[1, 1]; // cell 1, row 1
This is how you get the text of the entire row (as opposed to the existing answer that shows how to get a single value from a DataGrid):
string str = "";
int row = datagrid.CurrentRowIndex;
int col = 0;
while (true)
{
try
{
str += datagrid[row,col].ToString() + "|";
col++;
}
catch
{
break;
}
}