I have an object that has as one of its properties, a List. I want to bind a datagrid to that list, such that when I add objects to the grid, the datagrid updates. I tried:
myDataGrid.DataSource = myObject.MyList;
but when I update the datasource with new rows, the grid doesn't update.
Then I tried:
myDataGrid.DataSource = null;
myDataGrid.DataSource = myObject.MyList;
Calling the above code every time I added an item. This resulted in an error when clicking on the grid (specifically, index -1 has no data, something to do with the datagridview.get_current internally. Happens despite the fact that I'm not clicking the -1st row).
So then I tried:
myDataGrid.DataBindings.Add(new Binding("DataSoruce",myObject,"MyList",false,DataSourceUpdateMode.OnPropertyChanged));
That didn't reflect the updates either, so I added:
myDataGrid.DataBindings[0].ReadValue();
whenever I added an item, but it has no effect either. I feel like I'm circling around a simpler solution to this problem, but I can't seem to find it. Any pro tips?
You seem to already know this, but you want to use a BindingList if at all possible here. Any hamfisted attempt to make a List function like a BindingList is just going to be a lot more pain than simply copying the elements from a List you already have to a BindingList.
If I changed my type from List to BindingList, all the problems go away and the grid autoupdates as expected.
Related
So I have a databound listbox bound to a list produced from my entity:
myListbox.Datasource = myEntity.ToList();
That works fine. My question is, what is the 'correct' way to add a new element to the entity and have it reflected in my listbox?
Currently, I do this:
myEntity.Add(newItem);
myListbox.Datasource = myEntity.ToList();
Surely there is a better way than resetting the datasource each time?
try this, DataBind() will binds a data source to the invoked server control and all its child controls.
myListbox.DataBind()
Please try this:
myListbox.ResetBindings();
See https://msdn.microsoft.com/en-us/library/system.windows.forms.control.resetbindings%28v=vs.110%29.aspx
I want to create an application that is refreshing DataGridView content with data about surrounding Wifi networks on every second. I wonder what would be the best binding solution for this task. I think using BindingList is meaningless, because it would update the datagridview on every single update on the List, while it would be better to refresh it after whole List is updated. Meaby simple List and rebinding is appropriate here, what do you think?
You can prevent the DataGridView from updating on every change to your BindingList by the following
myBindingList.RaiseListChangedEvents = false;
// Update BindingList
myBindingList.RaiseListChangedEvents = true;
myBindingList.ResetBindings();
The ResetBindings() call will cause your DataGridView to be refreshed to reflect the changes to myBindingList.
Similar questions may exists, but none of them seems to be helpfull. So I'll try to explain a more specific case, and see if anyone can help me :)
Here is the thing, I have a gridview with templatefields, and I want to let the user to specify the order those columns are shown. So, the user creates a view and decides which column to display first, second, and so on.
So basically, I need to change the order of the columns just after the grid is loaded with data.
Sounds easy huh? Well, apparently it's not. At least I couldn't achieve that just yet.
Some notes:
- Of course I have AutogenerateColumns set to false.
- Change the sql select columns order won't work because of previous item.
- And I'd like not to generate the columns by the code.
Any ideas?
You can modify the Gridview's Columns collection in your code-behind. So, one way of doing this is to remove the column from its current position in the collection and then re-insert it into the new position.
For example, if you wanted to move the second column to be the first column you could do:
var columnToMove = myGridView.Columns[1];
myGridView.Columns.RemoveAt(1);
myGridView.Columns.Insert(0, columnToMove);
If you need to move them all around randomly, then you might want to try to clone the field collection, clear the collection in the GridView, and then re-insert them all in the order you want them to be in.
var columns = myGridView.Columns.CloneFields();
myGridView.Columns.Clear();
myGridView.Columns.Add(columns[2]);
myGridView.Columns.Add(columns[0]);
etc..
I'm not 100% sure whether this all will work AFTER binding to data, so unless there's a reason not to, I'd do it in Page_Init or somewhere before binding.
I know this is an really old question but the suggested answer did not solve the problem fully.
The ViewState for the GridView will failed after remove / add a dynamic column.
If you need to bind any event, like OnRowCommand and OnRowUpdating, such events will not be fired.
Edit:
Look into this function if you need answers.
Protected Overrides Function CreateColumns(dataSource As PagedDataSource, useDataSource As Boolean) As ICollection
I have bound my ListBox to some data.
The problem is when I call myTableAdapter.Fill(..) method, SelectedValue changes to whatever is the first item ID in the list. Although "Selected Value" in VS is not bound anywhere (see image).
alt text http://img370.imageshack.us/img370/2548/ss20090108212745qz2.png
How do I prevent this behaviour, please?
Thank you very much for helping.
You shouldn't be binding on each request. If you absolutely have to bind on each request for some reason you have to set SelectedIndex on the ListBox manually. This is because the Fill method first clears the list then creates new list items for the fetched data.
The simplest way I can think of is to change your table adapter fill code to something like this:
string preSelected = myDropDownList.SelectedValue;
myTableAdapter.Fill(myDataTable);
myDropDownList.SelectedValue = preSelected;
You will run into an issue if the item doesn't exist anymore, so you may want to add a condition to check for that.
How to remove selected items from ListBox when a datasource is assigned to it in C#?
When trying to remove, got error
"Items collection cannot be modified when the DataSource property is set."
But when i try to remove item from datasource (datatable) ,
it thorws error as "datarow is not in current row collection".
Find that item in the DataSource object and remove it, then re-bind the ListBox.
EDIT:
Here's how you delete from a DataTable as your DataSource, regardless of the .NET version.
DataRowView rowView = listBox.SelectedItem as DataRowView;
if (null == rowView)
{
return;
}
dt.Rows.Remove(rowView.Row);
I haven't tried with anything other than WinForms DataGridViews, but I highly recommend BindingListView, which is both faster than DataTables/Views and allows you to bind generic List<T>s as your DataSource.
Alternatively, use a list that implements IBindingList or inherits from BindingList. When objects are added or removed from a Binding List, any controls bound to it are automatically notified of the change and will update themselves accordingly. If you are using BindingList and your class also implements INotifyProperty changed, Any changes to class properties will also be updated automatically in the databinding control. For example, if a column in a datagrid(view) is bound to a property, "Name", and you change "Name" in the datasource, the datagrid will automatically update. If you add a new item to the datasource, the datagrid will update automatically. Binding List also supports notification in the other direction. If a user edits the "Name" field ina datagrid, the bound object will be updated automatically. Going off topic slightly, if you go a little further and impliment "SupportsSortingCore" and the associated methods in BindingList, you can add automatic sorting to your data. Clicking on a columnm header will automatically sort the list and display the header sort direction arrow.
If the ListBox has a datasource assigned, you must remove items from the datasource and then rebind the ListBox
You need to modify the data source rather than the Items collection of the control. Depending on what kind of data source you are binding to, there are going to be different things you have to do so that your UI updates.
The best way is find a collection that fits your needs and implements IBindingList or IBindingListView. Those two interfaces implement even handlers that listen for a CollectionChanged event and update your UI accordingly.
If your collection doesn't support those interfaces, you're going to have to re-bind your data source every time somebody adds/removes an item.
when you get the message "Items collection cannot be modified when the DataSource property is set."
setting the datasource to something else, empty list or null does not help when
the code initializecomponent is not completed.
to avoid that error, one must do the change of datasource or the item list during or after form load.
I know it does not seem to make sense. Hoever, the visual studio designer will generate code in the form designer.cs or vb that will add items to the listbox if any code that changes the items is found before end of initialize components
While Chris Doggett posted a valid solution, I ran into problems while using it. By using that method it was not allowing a subsequent GetChanges(DataRowState.Deleted) to work properly.
To better solve my problem, I only had to change a single line - the last line.
DataRowView rowView = listBox.SelectedItem as DataRowView;
if (null == rowView)
{
return;
}
rowView.Row.Delete();
This allowed my GetChanges call to work properly.
This worked for me
DataTable temp = (DataTable)lstBlocks.DataSource;
temp.Rows.RemoveAt(position);
its vary simple , assign a new blank value to listbox
eg..
Dim ABC As New List(Of String)()
ListBox1.DataSource = ABC
ListBox implementation is bugged, you need to create a new data source instance for the component for it to recognize a change.
Eg:
ActivitiesList.DataSource = _activities;
_activities = new List<Activity>(_activities);
_activities.Remove((Activity)ActivitiesList.SelectedItem);
ActivitiesList.DataSource = _activities;