Removing column based on the content of the cells - c#

I need to delete the whole column in a DataGridView based on a certain condition. My DataGridView columns consists of numbers (1,2 and 3) the condition would be to delete all columns that does not contain (1,2 and 3). For Example if the column has only (1 and 3) it should be deleted.
How do I Overcome this? as many threads I went through only cover when you are certain of an index like below.
myGridView.columns.RemoveAt(index);
Some suggest hiding columns and thats not what I want, I want to completely remove the column from the DataGridView.

While it's better to do the job using data source of the DataGridView, but if the control is not bound to a data source, you can also use linq to get values from columns and check for some criteria, for example:
dgv1.Columns.Cast<DataGridViewColumn>()
.ToList().ForEach(c =>
{
var values = dgv1.Rows.Cast<DataGridViewRow>().Where(r => !r.IsNewRow)
.Select(r=>r.Cells[c.Index].Value).ToList();
if (!values.Contains(1)) //your custom criteria
dgv1.Columns.Remove(c);
});
Here is a really simple test. Load dgv1 this way:
dgv1.ColumnCount = 2;
dgv1.Rows.Add(1, 2);
dgv1.Rows.Add(3, 4);
Then use above code to delete columns and it just removes the last column.

Related

VB.net sort column then sort off but retain rows position

I can sort datagridview column by automatic sortmode. But my problem is, when i set column is automatic sort that mean The "Status" column always in sort mode and if there have any data change it will move to anythere following sort mode
I don't wanna this. I just want sort on and then off but retain the row position. I mean:
step 1: when user change status of the "Status" column, it isn't sort data
step 2: then, when user click to column header, it sort data descending
step 3: after that, when user change any status of the "Status" column, it is not sort but retain rows position in datagridview (that mean row which status is changed, doesn't move to anywhere)
is there any right way to achieve this? Thanks you for you help.
Here's what I suggest in this situation:
If your grid is not already bound to a DataTable, do so.
Add an extra column to your DataTable with data type Integer.
Either create and bind your grid columns yourself and don't create one for that extra column or else hide that grid column after binding.
Sort your grid as desired.
Loop through the DefaultView of the DataTable and set the values in the extra column sequentially.
Assign the name of that extra column to the Sort property of the DefaultView.
That's it. The data is now sorted by that numeric sequence in that column so you can make whatever changes you want to the rest of the data without affecting the order.

Refresh Column order in DataGridView after adding column and using SetOrdinal

I have a DataGridView that shows summary data. It is bound to a BindingSource which is bound to a DataTable. Depending on the summary type selected by the user, the program may split the data into multiple columns. In my code, I update the existing column and add columns as needed. The new column, as expected, gets added to the end of the list and I use SetOrdinal to reposition it. The DataGridView, however never moves the column unless I blank and rebind the DataSource to the BindingSource as follows:
I add columns with the following code:
this.Columns.Add(newcolumn);
this.Columns[columnname].SetOrdinal(index++);
And I refresh the source as follows:
teamstats.UpdateColumn(teamstats.Columns[columnClicked].ColumnName);
bsTBAstats.DataSource = null;
bsTBAstats.DataSource = teamstats;
This is problematic, as after I refresh the DataGridView, I have to reapply my formats (cell formts and event handlers) for each of the columns which slows down the process significantly.
Is there a more efficient way to have the DataTable refresh the column order? If the user can reorder the columns manually, why can't I do it programmatically?
The best way I've found to accomplish what I asked above is to manually resort the columns in the DataGridView to match the order of the columns in the DataTable. The following codes shows the process I used:
foreach (DataColumn c in teamstats.Columns)
dgvTBAstats.Columns[c.ColumnName].DisplayIndex = teamstats.Columns.IndexOf(c);
Seems as though the binding process should automate this, but this works. Unfortunately, if the user has manually reordered the columns, that order is lost since the opposite is true and the DataTable doesn't get reordered to match the DataGridView.
I can't seem to find a better way to bind the column order.

c# add objects to table rows dynamiclly

I am trying to do something like this but I don't know how:
I have a table in c# which I increase and decrease during runtime.
Each row contains data, that is being parsed from an object.
I want to get an access to the object that the line is parsing, some a pseudo of it would be:
if (table.row.object == selectedObject)
I can't do it from the row number or something because the rows are being removed and inserted, each time with different objects.
any ideas, please?
EDIT: I am using TableLayoutPanel to work with a table, and this is how I add rows and removes them:
I am adding rows to the table dynamically, I have set of buttons and when I click one it deletes all old rows from the table and adds new rows that are related to this button.
This is the way I add new rows:
tlp.RowCount++;
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tlp.Controls.Add(new Label() { ... }, cellIDX, rowIDX);
// adding more columns //
and to remove old rows I loop through all rows from bottom to top, removes all related controls of the current cell, then I remove style and row num like so:
tlp.RowStyle.RemoveAt(rowNum);
tlp.RowCount--;
thank you
you can also see a previous question I had related to this subject:
C# change table row color when mouse hover
You can try having a new column in the table (call it original_row_no) and set the row values into that, before you start your insertion/deletion process. That way you can reference the row directly (this is in response to your final line which says "I can't do it from the row number or something because the rows are being removed and inserted, each time with different objects."
A better way is to have a unique id in the table and run your references against that.
It is much more easier to help if you show the code you are trying.

How to make a unique column in datagridview with c#?

how to prevent repeating of rows in datagridview while adding rows?
I need to make a unique column like in sql.
is there any way to do this via properties window or programmaticalLy?
You can check the existing unique column value before adding the new one, something like,
var rows = dataGridView1.Rows.OfType<DataGridViewRow>()
.Where(x => x.Cells["cell1"].Value == "newCellVal1")
.ToArray();
if (rows == null || rows.Length == 0)
{
//New row is unique
//Logic to add new row
}
else
{
//Row already exists with "newCellVal1"
//Update the existing value rows
rows[0].Cells["cell2"].Value = "newCellVal2"; //Coulmn "cell2" with a new value "newCellVal2"
rows[0].Cells["cell3"].Value = "newCellVal3"; //Coulmn "cell3" with a new value "newCellVal3"
}
Here, cellVal is the unique column name in the datagrid and newCellVal is the value of unique column from the new row. Also you can add combination of columns to check for unique values in the Any method.
Hope this helps...
I wanted to add it as a comment but I dont have the privilege . Just to give you a hint if you are populating your dgv using list or something similar you coud use the "distinct" function and give it a try. If you are reading some text file that you need to write some code to remove the duplicates.
to prevent user from adding new row, you can disable it from the properties window and set the allowusertoadd from true into false.
If you have a problem about the duplicate row or data, you have to check your datasources first.
And about making unique column, you can set it either from properties window and programatically.
Adding column from properties window, you can select the column properties and add or edit the column you want,
Programmatically, you can type this syntax :
datagridview1.columns.add("Column1");, etc
This is not done (directly) in the DataGridView.
You will, most propably, have bound the DataGridView to a DataSource like DataTable via .net data binding (a BindingSource). If not, do so right now by adding a DataSet to your project and create a new DataTable in it.
This (DataTable) gives you an in memory table of data, which can be populated with data in any way you like (loading from database, inserting programmatically).
You can then add constraints to columns of this table as described here.

Rearranged columns in C#

How can I get the rearranged columns out of a datagridview in C#? I need to get all the columns currently being displayed in order. I can get the default columns order by setting datagridview.AutoGenerateColumns=false but I get the same old order even after I've rearranged the columns in my table.
Edit: Basically what I need is to be able to iterate through all the columns of a datagridview based on their display index
Thanks
Use the DisplayIndex property of your DataGridView Columns.
The DisplayIndex property:
Gets or sets the display order of the
column relative to the currently
displayed columns.
Edit:
It's ugly, and I'm sure people are going to point and laugh, but this might give you a rough idea on one implementation to improve upon.
Create a DGV with three columns and set their DisplayName properties like so:
dataGridView1.Columns[0].DisplayIndex = 1;
dataGridView1.Columns[1].DisplayIndex = 2;
dataGridView1.Columns[2].DisplayIndex = 0;
Add the following code to loop through all the columns access the columns in the DGV in their DisplayIndex order:
for (int index = 0; index < dataGridView1.Columns.Count; index++) {
foreach (DataGridViewColumn c in dataGridView1.Columns) {
if (c.DisplayIndex == index) {
// You've got your next column.
Console.WriteLine(c.Name);
}
}
}
How are you selecting? SELECT *? You need to specify the columns in the order you want them.
Have you rearranged their order in the ItemTemplate section of your grid? You can also change the order via the context menu for a GridView, alternative you can change your SQL statement and make sure autogenerate is off

Categories