I have a method that I call in a form that returns a List and then I throw that into a BindingSource and throw the BindingSource into a DataGridView. The Order class has a property called Items that contains a List. My Order and Item class both implement the INotifyPropertyChanged Interface.
What I'm trying to do is that when a row is clicked in the DataGridView it pulls up the list of items associated with the order from it's Items property into another grid. I want to ensure that those items are 2 way binded to the grid but I can't call it the way I'd like to...
itemsGrid.DataSource = orderBindingSource[orderGrid.CurrentRow.Index].Items;
I can't access the properties of the list from within the BindingSource (After the . operator, Items is not an available option)... Any recommendations? I've tried using a BindingList<Order> and BindingList<List<Order>> but was getting implicit conversion errors. Any suggestions?
*EDIT: Ok I've managed to get the BindingList to work. I didn't know I had to add the list like this
orderList = new BindingList<Order>(Method To Retrieve List<Order>)
Aside from this, the first grid displaying the orders works and updates perfectly. The sub grid which contains the Order's Items bound like
itemsGrid.Datasource = orderList[ordersGrid.CurrentRow.Index].Items;
It displays properly. I don't have editing enabled as I have a few textboxes that are setup and each textbox is bound to the Item from the orderList of the currently selected row of the ordersGrid. I can update the data in the textboxes for the selected item in the subgrid but the changes when I leave the textbox, the sub grid's row for that item property edited does not update as I leave the textbox. It will, however, update if I select another item in the grid. How can I get it to update as I leave the textbox instead of having to click on another row in the grid?
Related
I encountered a very specific behave on the Comboboxes in Winform. I found a lot of quite similar questions, but no useful anwser to my problem:
I have a form where controls are bound to a SQL datasource via TableAdapter/manager. Some of the values are linked to Lookuptables which are of type Combobox. When I first fill the base dataset, all is shown correctly. I can choose items from Combobox (fields id and NamedItem) where "id" is bound as datamember to the base datset table and "NamedItem" is the DisplayMember of the Combobox.
No problems when changing values or updating but ...
once I have to refill the Combobox underlaying datasource (eg. in case, an entry was added), the selected Index of the Combobox is set to 0 - means, the first item in the list.
Sure, I could remember the selectedindex and restore it after. For one Combobox, no problem, but for dozens ...
Is there any other way to keep the last selecteditem after refilling the combobox?
If items would not be deleted from your combo list , turning the Clearbeforfill property of your Table Adapter to False can prevent that.
I am creating a ComboBox array dynamically and the DataSource for all the ComboBox is a single integer list that contains some integers. But when I change a value say X in any one combo box then all other combo values get reset to value X.
So here is the situation:
All combo box controls are bound to a single list
When I change selected item of a combo box, selected item of all other combo box controls also change.
How can I stop these behavior?
Since you are binding all combo boxes to the same data source - a single list - they are using a single BindingManagerBase.
So when you choose an item from one of combo boxes, the current Position of the shared binding manager base changes and all combo boxes goes to that position of their shared data source.
To solve the problem you can bind them to different data source:
You can bind them to yourList.ToList() or any other list for example different BindingList<T>.
combo1.DataSource = yourList.ToList();
combo2.DataSource = yourList.ToList();
You can use different BindingSource for them and set your list as DataSource of BindingSource
combo1.DataSource = new BindingSource { DataSource= yourList};
combo2.DataSource = new BindingSource { DataSource= yourList};
Also as another option:
You can use different BindingContext for your combo boxes. This way even when you bind them to a single list, they are not sync anymore.
combo1.BindingContext = new BindingContext();
combo1.DataSource = yourList;
combo2.BindingContext = new BindingContext();
combo2.DataSource = yourList;
In fact all controls of the form use a shared BindingContext. When you bind 2 controls to a same data source, then they also use the same BindingManagerBase this way, when you for example move to next record, all controls move to next record an show value from bound property of next record. This is the same behavior that you are seeing from your combo boxes. Being sync for controls which are using the same BindingManagerBase is a desired behavior. Anyway sometimes we don't need such behavior. The post shares the reason and the solution.
I would like my comboboxes to have the first value be empty so that the user can clear their previous selection. The comboboxes are bound to entities in the ViewModel. So how do I add this first value. I could used combobox.inert(0, new Entity), but is that the correct way?
This is for searching purposes: By default the combobox has no selection and the search will find everything. If they select an item the search is filtered.
As your ViewModel is responsible for preparing the data to be displayed by the View, the ViewModel should add the empty element at the beginning of the collection that is then bound to the combobox.
I have a Combobox, in which I would like its items to be the column data that is located on a DataGrid. Is there anyway to set the Combobox itemsource to be a specific column of a DataGrid?
Right now I'm iterating each row of the DataGrid, getting the field's data and adding them to the Combobox, but that means that I would have to clear all the items and reiterate everytime the DataGrid is modified.
You can set ItemsSource and DisplayMemberPath properties:
comboBox1.ItemsSource = dataGrid1.ItemsSource;
comboBox1.DisplayMemberPath = "ColumnName";
I Think you'are taking the wrong approach. Your data grid must be bound to a collection of object. I guess you could just build another collection by extracting the desired fields (for example with linQ) and expose this new collection to your view such that you can bind your combobox.
I you want to keep this second collection updated, make your first main collection an ObservableCollection such taht your can subscribe to CollectionChanged Event. In the event handler, just manage the add and remove in your combobox source collection.
I have a listview (in Details view) that is filled dynamically. I want to grab the text from the the first item in the listview.
This code doesn't work
lstSalesppl.Items[0].Selected = true;
string teamLeader = lstSalesppl.SelectedItems[0].Text;
I get an error on the second line: Invalid argument=Value of '0' is not valid for 'index' however the same code works in another method when the listview item is double clicked
Can anyone tell me what I'm doing wrong?
Thanks
try using
lstSalesppl.Items[0].Text
rather than
lstSalesppl.SelectedItems[0].Text;
lstSalesppl.SelectedItems may not be bound to the Selected attribute
ListView.SelectedItems Property
The SelectedItems property will not contain any items if the property is accessed before the ListView handle is created, which typically occurs when ListView is initially loaded for display in the form. You can check to see if the handle is created with the IsHandleCreated property. When the MultiSelect property is set to true, this property returns a collection containing the items that are selected in the ListView. For a single-selection ListView, this property returns a collection containing the only selected item in the ListView. For more information on the tasks that can be performed with the items in the collection, see ListView.SelectedListViewItemCollection.