I've a datagridview. I read an xml file and bind the data to the gridview. I change the xml and save it in another form. So i reread the xml file and i bind it to the gridview. The datatable is getting the updated values. But the grid is not getting updated till i close and open the application again. How to do it?
Thank you.
Regards,
Raghavendra
#1
Is there a Databind() or Rebind() for DataGridView? I set the datasource like this -
dvMoviesList.DataSource = dtMovies;
If i add any new row to the dtMovies table and set the datasource again, it is getting reflected. But if i edit the values of any of the existing rows and re assign the datasource it is not getting reflected till i close and open the application again. Any ideas?
Thank you.
I think you need to place a BindingSource in between the DataGridView and DataTable.
DataGridView _dgv = new DataGridView();
BindingSource _bs = new BindingSource();
DataTable _dt = new DataTable();
.
.
.
_dgv.DataSource = _bs;
_bs.DataSource = _dt;
Now whenever _dt gets updated, the BindingSource should take care of refreshing the DataGridView and you shouldn't have to worry about resetting any DataSource property. The DataSource properties can be set in the InitializeComponent() method (the designer), the Form's constructor, or Form.Load event handler.
I am sure what I am about to suggest is not the right way but I ran into the same issue and being an ASP.NET developer mostly and not having done much work in winforms the only solution I found was to set the datasource to NULL then rebind the data.
Example:
this.dataGridView.DataSource = null;
this.dataGridView.DataSource = myDataSource;
Going to verify the solution recommened by Nasser as the solution I have just does not seem right even though it works.
All you need is to Databind your datasource just like this
ArrayList list = new ArrayList();
list = YourXMLContent.GetItems();
GridView1.datasource = list; // you can use you DataTable instead of list
GridView1.update();
Gridview1.invalidate();
its all.
Have you tried this?
dvMoviesList.Refresh();
FYI: I've noticed a difference between setting the DataSource to a DataSet vs. a DataTable. Setting it to a DataSet does not cause the grid to refresh, even when it contains only one table. However, setting it to the DataTable inside the DataSet causes the grid to refresh correctly.
By the way, I was setting the DataSource property in an intermediate BindingSource object that was associated with the DataGridView, not in the DataGridView itself. Not sure if this matters.
This may only be tangentially related to the question, since the DataSource in the question was XML, not DataSet. However, others with my issue will probably bump into this topic (as I did), so I posted this anyway.
Related
I've set up a bound dgv to entity using dbcontext. Works fine. The rows are displayed in the dgv and I can modify cells and update using SaveChanges. However, if I attempt to add a new row in the dgv it doesn't get saved. If the dgv is bound to the entity shouldn't the new row get added automatically or do I have to do something to add it? What? Please provide example code. I'm going to try deleting from the dgv next. Will I have a similar problem? How might I get that to work? I scoured the internet for examples but they stop at binding the enitities and don't include addition or deletions. Any help would be appreciated.
I found a couple of links with a similar problem one of which is:
DataGridView AllowUserToAddRow property doesn't work
It seems that using .ToList messes up the binding. In my case I was using MyContext.MyTable.Local.ToList as the source. When I removed the .ToList everything works perfectly. Perhaps someone can tell us in more detail why this works???
Thanks to those of you that found this first.
Solution for .NET Framework 4
I have tried Removing the .ToList() but then I simply get no results.
So my workaround was:
For deletes:
On the datagridview UserDeletingRow Event
// Get deleted entity:
myEntityType currentEntity = (myEntityType)BindingSource[e.Row.Index];
// Delete directly from context
context.myEntityType.Remove(currentEntity);
For inserts:
On the save button I loop through the BindingSource and check if any enitity has an ID == 0 and then ADD each of those with context.MyEntityType.Add(currentEntity);
I have a dynamically created DataGridView that has a valid DataSource with one row bound to it. However, it is returning me 0 when I am doing a rowcount on the DataGridView.
dgResult.DataSource = resultDt; // a datatable containing one row
flowLayoutPanel.Controls.Add(dgResult);
int rows = dgResult.Rows.Count; // returning 0 always!
Can someone please tell me where I may be going wrong here?
I found the issue. I was displaying the grid in a tabbed page that was not selected. Unless the grid is visible, it does not raise the rowadded event (which is weird!) durnig databinding. I selected the tab page before doing the databind, and the rowcount worked.
Use this code instead:
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = resultDt;
dgResult.DataSource = bindingSource;
flowLayoutPanel.Controls.Add(dgResult);
var c = dgResult.Rows.Count;
The binding source is what's responsible for syncing your data with the control. You want to use it, rather than trying to assign the table directly to the control.
I have a simple datagrid listing addresses and a child window where the user can edit/add new. On the main form with the datagrid i have a button to "Insert New Address" which should load the child window with an empty Address object. However it will not let me add a record. Am i doing something wrong? my current code is as follows:
Dim address As New Address
Dim frmAddressObj As New frmAddress
If frmAddressObj.AddressDomainDataSource.DataView.CanAdd = False Then
frmAddressObj.AddressDomainDataSource.Load()
End If
frmAddressObj.AddressDomainDataSource.DataView.Add(address)
Address is the address object. frmAddress is the child window form. AddressDomainDataSource is the same datasource i use in the datagrid as i use in the child. CanAdd is always false and i got told to try loading before adding but this does not appear to have helped. When it reaches the Add method it returns an Exception of 'Add' is not supported by this ICollectionView. Any help would be appreciated. Thanks
The DataView field should be thought of as a read-only collection. The simplest general usage of the DomainDataSource with a DataGrid goes something like this:
(myDataSource.DomainContext as myDomainContext).my_entitys.Remove(dgOrders.SelectedItem as order);
(myDataSource.DomainContext as myDomainContext).SubmitChanges();
It is similar for insert, you just use
my_entitys.Add(myNewEntityInstance);
instead of
my_entitys.Remove(entityToRemove);
And for updates you simply call
(myDataSource.DomainContext as myDomainContext).SubmitChanges();
You must also have the insert method in your domain service. So make sure you have a method that looks like:
Public Sub InsertAddress(address As Address)
End Sub
or in C#
public void InsertAddress(Address address)
I had the same problem recently and in my case, the DomainDataSource wasn't loaded (or even bound to its context yet) because it resided in a TabItem that wasn't selected.
Make sure you have your DomainDataSource properly loaded in the visual tree, that solved the issue in my case.
I am building a winforms application, i have two comboboxes which have the same datasource, the datasource is a DataTable. Now, when I select a value in one comboBox, the value of another comboBox is changed too. Is there a way make it change without affecting the other?
In that type of scenario, you can create two different binding sources, one bound to each of your combo boxes. If you set the DataSource property of each of the binding data sources to your DataTable, then your combo boxes will work independently, while still showing the same data.
The initialisation would be something like:
// Initialization of the binding sources(assuming dataTable is a populated DataTable)
bindingSource.DataSource = dataTable;
bindingSource2.DataSource = dataTable;
The WinForms binding system is detecting that both comboboxes are hooked up to the same DataSource and is (helpfully) syncing changes across the two.
To avoid this you need to ensure each combobox has a distinct DataSource.
One way is to use the appropriate non-visual component from the Toolbox (BindingSource).
Another, if you're setting up your bindings with code, is to use BindingList. Note that there is one trap with BindingList - it can act as a wrapper:
[The] BindingList constructor creates a WRAPPER collection around the original list. It doesn't create a new list containing the same elements. (I've never seen this documented, but have verified with Reflector).
-- http://www.nichesoftware.co.nz/blog/200809/databinding-lists
Instead of:
editDebitAccount.DataSource = accountsList;
editCreditAccount.DataSource = accountsList;
use this:
editDebitAccount.DataSource = new BindingList(accountsList);
editCreditAccount.DataSource = new BindingList(accountsList);
Is there a way to get the wpf toolkit DataGrid to show new rows when its bound to a DataSet? In other words, I have a DataGrid, I've set its ItemsSource to a DataTable, and everything seems to work fine, except I can't get the grid to show rows that I add to the DataTable programatically.
You can set the datagrid.ItemsSource to an ObservableCollection<T>.
ObservableCollection<YourItem> items = new ObservableCollection<YourItem>();
yourDataGrid.ItemsSource = items;
Then you should be able to just add to the collection to get the new rows to appear:
Edit: Based on updated info.
if (Dispatcher.CheckAcces())
{
// already on thread UI control was created on
items.Add(<your item>);
}
else
{
// update on same thread UI control was created on
// BeginInvoke would invoke a delegate which would call items.Add(<your item>)
Dispatcher.BeginInvoke(...);
}
See Dispatcher. All System.Windows.UserControl objects have a Dispatcher property.
I'm not sure how anyone would have figured this out, especially since I didn't mention it, but the problem was that I was updating the dataset from a thread other than the form's main thread, i.e. the thread that the grid was created on. You can do updates from another thread, but you can't do inserts, although I don't know why. If someone could shed some light on that, I'd appreciate it. My guess would be that the grid checks to see if the insert is coming in on another thread, and if so, it ignores it because that would cause an exception.