DateGridview with checkbox column - c#

In my datagridview there is checkbox column. Based on the values in the database want to check the checkbox in the datagridview during runtime and display it to the user.
for (int i = 0; i < supName.Count; i++)
{
foreach (DataGridViewRow row in dataGridView2.Rows)
{
int supId = Convert.ToInt32(row.Cells["supplierId"].Value.ToString());
if (supId == supName[i])
{
row.Cells["selectSupplier"].Value = true;
}
}
}
For one Item there can be multiple suppliers. When adding a new Item to the database, all the existing suppliers are displayed in a datagridview. In this datagridview there is a checkbox column which allows user to select relevant suppliers.
When retrieving information about an item I want to check the checkboxes of the suppliers user has selected for that particular item in the, above mentioned datagridview (datagridview with all the existing suppliers).
Above is the code that I have used to check the checkbox but it the checkbox is not selected.
checkbox column name is "selectSupplier".
Thank You

Your nested loop checks a row if supName list contains the row's supplierId. First issue I found was that if you don't have "AllowUserToAddRows" set to false, your inner loop will try to parse a blank row to integer and throw an exception. This stresses the importance of try-catch blocks and proper error handling.
Your method is also quite inefficient, order[n*m]. Ultimately, most of us will recommend using data binding (https://msdn.microsoft.com/en-us/library/fbk67b6z%28v=vs.90%29.aspx). You can "link" your database table directly to your DataGridView and the supplier ID and check come for free. You will likely need a simple LINQ command (https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b) to perform the supplier "exists" verification.
If you don't want to or cannot use data binding, you can perform the same result with just your inner loop and use supName.Contains(supId) for order[m].

Related

Select multiple Rows with UltraGrid

I am new to Infragistics using UltraGrid.
I am trying to select multiple rows using checkbox column (or if there is another idea)
I have a code for DataGridView to select multiple rows and insert it to list, than try to delete or to do code with selected items.
//get the selected item
List<DataGridViewRow> selectedRows = (from row in Detail_shanuDGV.Rows.Cast<DataGridViewRow>()
where Convert.ToBoolean(row.Cells["checkBoxColumn1"].Value) == true
select row).ToList();
But when I try to use this code with UltraGrid like this
List<UltraGrid> selectedRows = (from row in ultraGrid1.Rows.Cast<UltraGrid>()
where Convert.ToBoolean(row.Cells["caption"].Value) == true
select row).ToList();
It gives me this error
'UltraGrid' does not contain a definition for 'Cells' and no extension method 'Cells' accepting a first argument of type 'UltraGrid' could be found
So if theres another idea or how to find solution to solve this error.
By the way I am using hierarchical UltraGrid with checkbox column, in my UltraGrid I have Master/Details data
You should cast to UltraGridRow not to UltraGrid
List<UltraGridRow> selectedRows = (from row in ultraGrid1.Rows.Cast<UltraGridRow>
where Convert.ToBoolean(row.Cells["caption"].Value) == true
select row).ToList();
Also, probably you need another level of filtering on those rows. For example, it is not clear if the checkbox for the column Caption is on the master or in the details pane of the grid. Also if you have a GroupBy display option then you need to add also another condition to filter only the required rows
For example, suppose that you want to apply this logic but only the rows that are in the details pane. In Infragistcs terms this second pane is called Band and every row has a property for the Band to which it belongs. And the Band has a property Index, so you get
List<UltraGridRow> selectedRows = (from row in ultraGrid1.Rows.Cast<UltraGridRow>
where row.Band.Index == 1 &&
Convert.ToBoolean(row.Cells["caption"].Value) == true
select row).ToList();
Notice that you first check for the Band index and only if this row is on second band you check for the cell value (Because If there is no "caption" column in the first band you get an NRE)

When DataGridView is sorted, how do I update the data source to reflect the DataGridView's binding?

I have these members on my DataGridView.
private DataTable _dataTable = new DataTable();
public DataTable DataTable {
get { return _dataTable; }
set {
_dataTable = value;
int rowIndex = -1;
//want to preserve the location where the datagridview is scrolled to
if (this.Rows.Count > 0) rowIndex = this.FirstDisplayedScrollingRowIndex;
this.DataSource = new BindingSource() { DataSource = _dataTable };
//-1 is out of bounds and the datasource could have been set
//to a smaller amount of rows after the rowIndex was set
if (rowIndex > -1 && rowIndex < _dataTable.Rows.Count) this.FirstDisplayedScrollingRowIndex = rowIndex;
}
}
When rows are added, removed or edited they are done so in _dataTable. When the rows are changed, DataTable is set so that the DataGridView displays the changes by binding the data to it. My problem is when the DataGridView is sorted by clicking one of the column headers. This changes the display of the DataGridView, but not the order of the rows in the underlying DataTable. How can I get it so _dataTable is sorted like the DataGridView?
I have considered adding a column to keep track of row indexes, but it seems like there should be another way and I don't really want to add a column since this is an abstract class. I have tried handling it in the DataGridView.Sorted events but haven't come up with any solutions that would work.
There is no way to transfer the sorting of the view into the table - not any that are provided by the DataGridView or DataTable classes. Why would you want to? If you are sorting based on a column, that column is in the table, and will be in the table any time you want to iterate through or sort the table in the order of that column.
If you want to persist the user's choice of sort column for the view, that is a different kettle than trying to save the specific sort position for each row. I would recommend just saving what column the user chose. This would not belong in that same table, but in a separate settings storage. If you absolutely want to store the sort position of each row, then you do need a separate column that has the sort order for each row, and you will need to capture the header mouse click event and repopulate that column appropriately.
Also, the minute you add a sort-order column to that table, that is dependent on what column the user chose to sort the data, you de-normalize the data. This means you will run into problems of maintaining data integrity - you will have to capture all sort of events and re-update that column... for example, what if the user changes the value for a row in the middle of the table, such that it now belongs at the end... update the value of that sort order column for that row and every row between its old and new position. What if the user deletes a row - update the value of the sort order column for all rows between the deleted row and the last row of the table.... and on and on with all sorts of user operations.
Much better, store the column name in a setting, and whenever the table is loaded into the gridview, tell the gridview to sort on the column stored in that setting. I am not sure if I am being clear - sorry.
Well explained on msdn. You have to set Columns SortMode and the direction ascending/descending.

Issue using counters in datagridview c#

I have datagridview table. Whenever a user selects row and click 'Update Counter' button, counter value changes to 1 at top corner of window.
Now if a user selects the same row, the counter is updated incrementally which I don't want. I don't want counter to update on same row selection.
My code -
Int32 selectedRowCount = dataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected);
for (int i = 0; i < selectedRowCount; i++)
{
// need to insert condition so that counter is not updated when same row is selected again.
Counter.Text = Convert.ToString(i + 1);
}
}
I new to C# development, please provide changes.
Without seeing the rest of the code, or really understanding what you are doing (is this list going to change, what is the counter, can you identify the selected row easily?), all I can really suggest is maintaining a list of selected rows and checking that before updating the counter.
For example, in the for each:
if (selectedRows.Contains(rowIdentifier)) continue;//if you want to keep looping, otherwise break;
You may use the Tag property of the DataGridViewRow to identify rows already selected.
foreach (DataGridViewRow r in dataGridView1.SelectedRows)
if (r.Tag!=null) { Counter.Text=int.Parse(Counter.Text)+1 ; r.Tag=True ; }
I would add a condition statement that checks to see if the variable is dirty or has already been updated. This sounds similar to a concurrency issue or checking concurrency, I'm sure if you searched for ways to resolve concurrency issues the logic used would be similar. I agree with #johnc
I would utilize the onclick event then disable the ability to click the same row again.
OR use some other unique property of the row and check against it.
if(row.uniqueProperty == -1)
{
Counter.Text = Convert.ToString(i + 1);
}
Basically, I created a SQL table storing all values from selected row. If selected row value is something already there in the table, the counter doesn't get updated while the counter gets updated when unique row is selected.

Datagridview and checkboxlist

I have a question. Let's say i have a checkboxlist with the ingredieints for a cake and i choose not just one but more ingredients (3-4). I want to save this in datagridview. Can datagridview show more than one ingredient or is this not possible ?
You see i'm making an application for bakeries and for ordering cakes you will choose the type of cake and adding(toppings) and the number of cakes you want. Then I would like to save this to datagridview, or show this in dgv and then when I would finish with ordering i would just click on send button in dgv and all the orders i made would be sent to an email. I hope you understand what i want.
Even in its simplest uses a DataGridView is a 2-dimesional container; a 'grid', so you can have as many rows and columns as you want.
If you want to display them all in row you should first try to estimate the maximum number of ingredients. Then you add this number of columns to the target DGV.
Then add a row and fill its column cells with the ingredients.
In case you come across a cake with even more ingredients that would't be a problem either as you can always add more columns.
Empty cells are no problem, just make sure to always check for null values.
By the way, cells are quite powerful and you can have a tag for each single cell, so you can add as many data of any complexity to the cell beyond its mere value!
Here is some simple sample code:
while (dataGridView1.ColumnCount < checkedListBox1.CheckedItems.Count)
dataGridView1.Columns.Add("", "");
int newRow = dataGridView1.Rows.Add();
int item = 0;
foreach ( object o in checkedListBox1.CheckedItems)
{
dataGridView1[item, newRow].Value = o.ToString();
item ++;
}

Method to find DataGrid Row is selected or not?

I am new to C# and WPF. Issue I have is on datagrid I am displaying datatable data. I need to update data based on selected row. I am able to achieve that.
However, when I do not select any row on datagrid it does select default row as '0' and I do not want that I want result as -1 or error because I have not selected any row there?
You can determine if a row is selected with dataGrid.SelectedIndex; if the value is >= 0, you have a row selected.
To access the selected row:
if (dataGrid.SelectedIndex != -1) {
YourDataType row = (YourDataType)dataGrid.SelectedItem;
// process stuff
}
In the event that you allow multiple selections in your data grid, a very reasonable assumption, you can access the collection with the dataGrid.SelectedItems property.
A similar answer that shows example XAML too can be seen here: Get selected row item in DataGrid WPF
Not very clear about what actually you wanted to do. Just set yourdatagrid.SelectedIndex=-1; in some sort of initialization part of your code.

Categories