DataGridView get actual order - c#

HI, I've a DataGridView with this setting: d
dataGridView1.AllowUserToOrderColumns = true;
(so the users can reorder columns)
My problem is that I want to know the current order of columns.
I've done this methond:
public List<int> getActualTaskOrder() {
List<int> ris = new List<int>();
int i=1;
while(i<this.dataGridView1.Columns.Count){
DataGridViewColumn c= this.dataGridView1.Columns[i];
if (c.Name != "**")
{
Console.WriteLine(c.HeaderText);
ris.Insert(c.Index-1, System.Convert.ToInt32(c.Tag));
}
i++;
}
return ris;
}
my problem is that the result (the order of columns) is always the same (also if I move columns in my gui)

You need to look at the DisplayIndex of your columns; perhaps something like:
var qry = from DataGridViewColumn col in grid.Columns
where col.Name != "**"
orderby col.DisplayIndex
select col.HeaderText;
foreach (string txt in qry) {
Console.WriteLine(txt);
}

Related

Issue with setting primary key for DataTable merge, over combobox WPF in C#

Combobox gets populated as such:
foreach (DataColumn item in Dt_Masterlist.Columns)
{
Combo_Master_Primary.Items.Add(item.ColumnName);
}
Now im trying to get the selected column from the combobox to set it as primary key to later merge 2 datatables with each other.
DataColumn primarymaster;
//getting the DataColumn[] from Columns with the choosen Columnname by Combobox
foreach (DataColumn item in Dt_Masterlist.Columns)
{
if (item.ColumnName == Combo_Master_Primary.SelectedItem.ToString())
{
primarymaster = item;
Dt_Masterlist.PrimaryKey = item;
}
}
Dt_Masterlist.Merge(Dt_NewList);
I get the following error:
"Type System.Data.DataColumn cant be converted implicit to System.Data.DataColumn[]"
How could i fix this issue?
Greetings
SaltTM
Came up with a solution, got confused by the "new" tag.
int count = Dt_Masterlist.Columns.Count;
for (int i = 0; i < count; i++)
{
if (Dt_Masterlist.Columns[i].ColumnName == Combo_Master_Primary.SelectedItem.ToString())
{
Dt_Masterlist.PrimaryKey = new DataColumn[] {Dt_Masterlist.Columns[Dt_Masterlist.Columns[i].ColumnName]};
}
}

How to add each row value while iterating DataGrid?

I got a DataGrid with filtering, and I want to get the total sum of each column in this grid. At this moment I have an iteration through the filtered DataGrid, but I have no idea how to access the numbers and add them together.
private void Calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
{
var tb = sender as System.Windows.Controls.Calendar;
CollectionViewSource addedFoodsViewSource = ((CollectionViewSource)(this.FindResource("addedFoodsViewSource")));
if (tb == null)
{
fooddatabaseDataSet1.AddedFoodsDataTable dt = addedFoodsViewSource.Source as fooddatabaseDataSet1.AddedFoodsDataTable;
dt.DefaultView.RowFilter = null;
return;
}
else
{
string txt = tb.SelectedDate.ToString();
fooddatabaseDataSet1.AddedFoodsDataTable dt = addedFoodsViewSource.Source as fooddatabaseDataSet1.AddedFoodsDataTable;
dt.DefaultView.RowFilter = string.Format("AddedDate LIKE '%{0}%'", txt);
}
Int32 sum = 0;
for (int i = 0; i < addedFoodsDataGrid.Items.Count - 1; i++)
{
}
}
You can calculate the sum of each column going through all the items and invoking GetCellContent method on particular column.
Here I assume that you have DataGridTextColumn to store your data.
private long GetColumnSum(DataGridColumn column)
{
long result = 0;
foreach (ItemCollection item in addedFoodsDataGrid.Items)
{
result += int.Parse((column.GetCellContent(item) as TextBlock).Text);
}
return result;
}
To get filtered data you don't use the DataGrid itself, you use the underlying DataView. You may iterate through the view itself:
foreach (DataRowView rowView in dt.DefaultView)
{
var row = rowView.Row as AddedFoodsDataRow;
// Do something //
}
... or export it to a table:
var filteredData = dt.DefaultView.ToTable();
or, if you want the third column:
var sum = filteredData.AsEnumerable().Sum(x=>x.Field<int>(3));
or, if you want to access the column by name
var sum = filteredData.AsEnumerable().Sum(x=>x.Field<int>("SomeProperty"));

How to remove specific index from a list of datagridview rows

How to remove list of datagridview at specific index c#
List selectedRows = (from row in dataGridView2.Rows.Cast()
where Convert.ToBoolean(row.Cells["checkBoxColumn"].Value) == true
select row).ToList();
when this linq statement execute it will add whole row in selectedRows, i do not want to add coulmn 0 and 1 in List selectedRows so how i will achieve this ?
you have to provide list of column you want to select in select new as given below that will resolve issue
List selectedRows = (from row in dataGridView2.Rows.Cast()
where Convert.ToBoolean(row.Cells["checkBoxColumn"].Value) == true
select new {
Field1 = row.Field<string>("Field1"),
Field2 = row.Field<string>("Field2")
}).ToList();
Yes its a window form
i make checkbox using collection property of datagridview named as Select
i want to execute below code upon changing status of checkbox to check
foreach (DataGridViewRow item in dataGridView1.Rows)
{
if ((bool)item.Cells[0].Value == true)
{
int n = dataGridView2.Rows.Add();
dataGridView2.Rows[n].Cells[0].Value = false;
dataGridView2.Rows[n].Cells[1].Value = item.Cells[1].Value.ToString();
dataGridView2.Rows[n].Cells[2].Value = item.Cells[2].Value.ToString();
dataGridView2.Rows[n].Cells[3].Value = item.Cells[3].Value.ToString();
dataGridView2.Rows[n].Cells[4].Value = item.Cells[4].Value.ToString();
dataGridView2.Rows[n].Cells[5].Value = item.Cells[5].Value.ToString();
dataGridView2.Rows[n].Cells[6].Value = item.Cells[6].Value.ToString();
dataGridView2.Rows[n].Cells[7].Value = item.Cells[7].Value.ToString();
dataGridView2.Rows[n].Cells[8].Value = item.Cells[8].Value.ToString();
dataGridView2.Rows[n].Cells[9].Value = item.Cells[9].Value.ToString();
dataGridView2.Rows[n].Cells[10].Value = item.Cells[10].Value;
for (int i = 0; i < dataGridView2.Columns.Count; i++)
if (dataGridView2.Columns[i] is DataGridViewImageColumn)
{
((DataGridViewImageColumn)dataGridView2.Columns[i]).ImageLayout = DataGridViewImageCellLayout.Stretch;
break;
}
foreach (DataGridViewRow row in this.dataGridView2.Rows)
{
row.Cells[0].Value = true;
}
}
}
above code is lies between button click event

Check and replace the values in each cell of a DataTable using ItemArray

I have a datatable with 10 columns. I have to check if the cell values in each of the columns contains value A or D, if so I have to replace 'A' with '150' and 'D' with '250' respectively.
I am trying with this ::
foreach (DataRow dr in dt.Rows)
{
foreach(var item in dr.ItemArray)
{
if( item.ToString()=="A")
{
item.ToString().Replace("A", "150");
}
if (item.ToString() == "D")
{
item.ToString().Replace("A", "250");
}
}
}
but the values are not replaced. Why is it so? What is the error with this code ?
Replacing a string is not the whole point in the question. There are some important points, which are ignored by the other answers.
Assigning a value to an element of the item array will not change column value.
Assigning value to a variable containing the column value will not change the column value.
To replace column values using ItemArray, you need to assign a new array the ItemArray property.
When trying to replace the ItemArray property, if there is a read-only column, then setting item array will throw an exception.
And the point which is already mentioned by other answers, Replace method of the string will return the result replaced string, it will not change the source string.
Just for your information to have a better understanding about ItemArray property, it's the way that the property works, (in short):
Public object[] ItemArray {
get {
var values = new object[Columns.Count];
for (int i = 0; i < values.Length; i++) {
values[i] = Columns[i];
}
return values;
}
set {
for (int i = 0; i < values.Length; i++) {
//Checks if the column is writable and value is valid
Columns[i] = value[i];
}
}
}
You can read the whole source code as well.
So as a conclusion, the following pieces of code are wrong and will do nothing for you:
Wrong: row.ItemArray[i] = "something"; → Will not change column[i]
Wrong: var item = row[i]; item = "something"; → Will not change column[i]
Wrong var s = "something"; s.Replace("s", "x"); → Will not change s.
Example - Using ItemArray
Please be aware, if there is a read-only column in the data table, the following code will raise an exception:
foreach (DataRow r in dt.Rows)
{
var a = r.ItemArray;
for (int i = 0; i < dt.Columns.Count; i++)
{
if ($"{a[i]}" == "A") // if($"{a[i]}".Contains("A"))
a[i] = "150"; // a[i] = $"{a[i]}".Replace("A", "150");
if ($"{a[i]}" == "D")
a[i] = "250";
}
r.ItemArray = a;
};
Example - Using Columns Indexer
foreach (DataRow r in dt.Rows)
{
foreach (DataColumn c in dt.Columns)
{
if (c.ReadOnly)
continue;
if ($"{r[c]}" == "A") // if($"{r[c]}".Contains("A"))
r[c] = "150"; // r[c] = $"{r[c]}".Replace("A", "150");
else if ($"{r[c]}" == "D")
r[c] = "250";
}
}

Reading data from dataGridView instead of a csv file in C#

I have written a C# code to read data from a csv file. The data is in the form say:
2,3,4,5,6
4,2,4,5,6
4,5,6,3,2
5,3,5,6,3
The code to read it is:
var lines = File.ReadLines("Data.csv");
var numbers = ProcessRawNumbers(lines);
The function ProcessRawNumbers is as follows:
private static List<List<double>> ProcessRawNumbers(IEnumerable<string> lines)
{
var numbers = new List<List<double>>();
/*System.Threading.Tasks.*/
Parallel.ForEach(lines, line =>
{
lock (numbers)
{
numbers.Add(ProcessLine(line));
}
});
return numbers;
}
private static List<double> ProcessLine(string line)
{
var list = new List<double>();
foreach (var s in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
{
double i;
if (Double.TryParse(s, out i))
{
list.Add(i);
}
}
return list;
}
I would like to do the same with DataGridView. How can this be achieved?
In DataGridView I give input as follows:
Also, is it possible to have the number of columns change dynamically?
Data entered in a DataGridView is stored in its rows and cells. To exctract the data, you have to manually iterate over the rows and cell:
public List<string[]> ExtractGridData(DataGridView grid)
{
int numCols = grid.Columns.Count;
List<string[]> list = new List<string[]>();
foreach (DataGridViewRow row in grid.Rows)
{
if (row.IsNewRow) // skip the new row
continue;
string[] cellsData = new string[numCols];
foreach (DataGridViewCell cell in row.Cells)
if (cell.Value != null)
cellsData[cell.ColumnIndex] = cell.Value.ToString();
list.Add(cellsData);
}
return list;
}
If you want to change the columns dynamically, you can access the Columns property of the grid. For example, to add a column you can write:
dataGridView1.Columns.Add("NewColumn", "New Column");
Also note that using Parallel.ForEach in your scenario has no advantage, because you have to process the data sequentially, and by using lock statement, you forced the sequential processing. So there is no parallel proccessing.

Categories

Resources