Binding winform listview to dataTable - c#

Is there any way to bind a winform ListView to a DataTable (or perhaps a list), in a similar manner in which it's done in a listview from visual web gui (in the last one, the listview has a dataSource property to do so)?
I know it can be done by, going through each of the table's elements and adding them to the ListView, but I would like to avoid using a foreach instrucction each time I have to fill a listview, or creating a method that recieve a listview as parameter and which fills the listview using a foreach.

As far as ListView is concerned there is no direct way of setting its data source to a data table or similar. The only way is to iterate the data table or list and manually fill the items of ListView.

Related

Can't manually add item to listbox that is populated iterating through a list

In a C# WinForms project I'm querying a database to get a list of values to populate a listbox with. The query populates a List and then I iterate through that to add the list items to the listbox.
lsNewValuesList = dbGetNewValueInfo.GetNewValuesDgvData(strNewValuesQuery);
foreach (string strItem in lsNewValuesList)
{
lsBxNewValues.Items.Add(strItem);
}
After that's done, I need to manually add an item to the top of the list, which I'm doing via, lsBoxNewValues.Items.Insert(0, "DELETE");. But when I run it I get the message,
Items collection cannot be modified when the DataSource property is set.
Here is a screenshot of the error (to clarify some questions):
Looking into that I'm understanding that error arises when the listbox is populated with a datasource, but I'm just populating it from a string list. Is that, technically, a datasource then?
How do I accomplish what I'm trying to do?
[UPDATE]
Okay, I've done some fiddling around, albeit without resolving my issue, and I've tried the following:
lsNewValuesList = dbGetNewValueInfo.GetNewValuesDgvData(strNewValuesQuery);
lsNewValuesList.Insert(0, "DELETE");
lsBxNewValues.DataSource = lsNewValuesList;
//foreach (string strItem in lsNewValuesList)
//{
// lsBxNewValues.Items.Add(strItem);
//}
Instead of inserting "DELETE" in the ListBox (which is what I was originally trying and was causing the error), I inserted it at index 0 of the List, the datasource of the ListBox, and then set the ListBox's datasource. "DELETE" is showing up in the ListBox, but it's getting alphabetized along with the rest of the items. I'm not doing any sorting of the list or the ListBox - I'm using ORDER BY in the database query, however. CyberZeus suggested I use Refresh() on the ListBox, but that didn't have any effect.
Yes, a list of strings is a datasource.
You have to add the data retrieved from the database to the datasource of the ListBox. You may need to refresh the ListBox.

Reload DataGrid with DataSource is too slow only when DataGrid is on the current active tab

I have TabControl and DataGrid with DataSource in one of the tabs .
When I "Reload" my DataSource (pull data from DataBase, clear DataSource and fill it again with the objects), it is too slow (a half an hour or more, for 65000 records) if current active Tab is tab where is the DataGreed. If some other Tab is active it takes 2 minutes.
I just do test with "visible=false" for DataGrid and it work fast, as normal, but it is not an option, I wanna that client see DataGreed during its reload.
It looks as the DataGrid does "something" (which slow down) after adding every single row in DataSource.
AutoSizeColumnsMode is already None
Is there any trick how I can solve this problem? any advice is appreciated.
You can try to use Background Worker to fill DataGridView.
Also what I noticed that Telerik RadGridView loads its data dynamically when moving ScrollBar.
Loading DataTable Slow When Bound to DataGridView.Datasource
To avoid rendering every row in DataGrid one by one, I set:
myDataGrid.DataSource = null;
After it fill my dataSource with the data, and after it back my original binding source.
myDataGrid.DataSource = originalBindingSource;
Problem here could be only that we will empty DataGrid during the reloading (because DataSource = null).
We can make another helping collection and set it as a DataSource, until originalDataSource is filling.

edit multiple rows selected in a GridControl in TextEdits bound to the same bindingsource

My setup:
C#.Net 4.0, Windows Forms, DevExpress 13.1.5 although I doubt its a DX issue
I have a form with a GridControl (with GridView) on the top and a detail area that holds TextEdits and other edits in a LayoutControl below.
Both the grid and the edits below are bound to the properties of the objects contained in a list in the binding source.
The grid is set to ReadOnly, MultiSelect, RowSelect and all its columns are set to ReadOnly, not focusable.
Editing is only happening in the detail area below.
The behavior I want to create:
When multiple rows are selected in the grid the edits below should show the following:
the value of field in question is the same in all selected rows -> show the value
the value of the field in question differs between the rows -> show nothing
if the user writes into the TextEdit while multiple rows are selected:
the value of the edit should update the values of the same field of all the selected rows
Where I am with this:
I'm working on a solution by building a custom BindingSource that would be aware of the selection. It would bind the list of object to the grid and a single object that is not part of the list to the edits. Depending on the selection I would set the properties of that single object or forward its changes to the selected objects in the list.
I got that working for a single property with 2 binding sources and would now extend it to use reflection to do this for all of the public properties. I also want to encapsulate the whole behavior into a class that looks and acts like BindingSource just with that added behavior.
The question:
Is there a simpler way to achieve this? Does something already exist which can do this that I overlooked in either .Net or DevExpress? Are there traps to my approach that I should consider or why I should go about this totally differently?
I think that you can achieve your goal in a simpler manner:
Just bind a single BindingSource with all the data that you need to your grid. That should display the data.
Then, bind the required fields from that same BS do the edits through the DataBindings propriety.
You can then implement a save object (through a control or programatically) so the changes made in the edits are shown in the grid.
To check the grid values, you can use:
//get the handles of the rows
gridView.GetSelectedRows();
//get the value of the desirable cells
gridView.GetRowCellValue(handle, column);
Also, in future projects, consider using the Entity Framework to construct a data-aware model and custom objects based on the elements of your Database.
Hope this helped!

How can I access Column names in datagrid programatically at run-time in C#

Background to the Question
Working in C#
I have a datagridview that is populated by a generic db method that exposes a data adapter and a binding source. The binding source is the datasource for the datagrid.
e.g. dgrid.DataSource=bindingSource;
I use the same generic db method to retrieve data from multiple tables and the same datagrid to display the data retrieved - so by varying the sqlcommand the datagrid display data from any specified db table on a SINGLE form using a SINGLE datagrid.
This reusable method allows me to displays data from any table in a single datagrid on a single form.
Logical Flow
Data from DB-->Assigned To BindingSource-->Assigned To DataGrid
The QUESTION
Typically I would reorder the columns on the datagrid using the 'Edit Columns' dialog but the datagridview in this case only exists at run-time.
Since the datagrid column names are not known until runtime ie until the binding source is invoked how do I programmatically access the column names, once the binding is complete, in order to reorder the columns and to facilitate further data manipulation?
Thanks in advance.
Just to know the column name after binding has been done, you can use :
GridView1.Columns[Index].HeaderText

DataGridView bound to Linq to SQL does not show new rows added elsewhere to DB context

I have a DataGridView bound to a LINQ to SQL query expression. I want it to be editable for updates, but for inserts I want users to use separate controls below the grid (textboxes, date pickers, etc - currently not bound to anything). I have an "Add" button that creates an object of the linq to sql entity class based on the values in the controls, and then calls InsertOnSubmit(). When I later call SubmitChanges(), any updates from the grid, and any objects added are all correctly persisted to the database.
My problem is that any new objects are not added to the grid, before or after the call to SubmitChanges(). I would like new objects to be added to the grid as soon as they are created. Also, I only want the controls below the grid to be used for inserting new records, not editing existing records, so I don't think they should be bound to the data source...What is the best way to make this happen?
I did try simply re-setting the DataSource for the grid (ie dataGridView.DataSource = db.<TableName>, which works, but is clumsy because it scrolls to the top of the grid again - I'm sure a better method exists.
(Pls excuse the n00b question, I'm very new to all this .net stuff :P)
The first thing to try is GetNewBindingList(), but this thread: "Linq-SQL canonical editable datagridview sample code" has some thoughts for other scenarios.

Categories

Resources