How can I add items after setting itemsource to ListView - wpf

I got exception :
Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.

You must add the items to your source-collection that is set to ItemsSource. After you have set the ItemsSource-property to a value, its no more possible to use the Items-property (besides you set ItemsSource newly to null). Items and ItemsSource exclude each other.
If you use ItemsSource, your source-collection must implement INotifyCollectionChanged so that it will inform the ListView about changes. If not, added items to it will not change the ListView. E.g. if you use List<T> as items-source, changes will not be forwarded.
There exist classes that do that for you such as ObservableCollection<T>.

Related

Silverlight: Two-way Binding for a DependencyProperty (IList) not working

Well..its working BUT only when user creates a property that is of type List.
Here's the complete scenario.
I have a templated control (Multi Select ComboBox with Checkboxes)
User gives a List/ObservableCollection as its ItemsSource. The collection can be of any type (Employee, Chair, Person etc). The DependencyProperty for ItemsSource is of Type IList.
User can also give a List with two-way binding in a DependencyProperty called SelectedItems (so that he can show some items as checked and get back the items which gets checked)
Now the issue is with the SelectedItems dp. It is of type IList in the templated control.
The two-way binding does not work if user has bind it to, say, List<Person>.
But it works if List<Person> is changed to List<object>.
I cant figure out what is it that I am not doing right!
It doesn't make sense to place a TwoWay binding on the SelectedItems property. This would imply that the control should create and assign an instance of an object implementing IList to the property on the source object. However there is no way for control to know what actual type to create to assign to the property.
Instead you should be using a OneWay bind to a List that pre-exists in the source object albeit an empty one. The controls task then is to simply add or remove members in that list from the list supplied in the ItemsSource property.

Updating an Observable Collection Based on a combobox selection

So I have an ObservableCollection of items called "Class1" and
Class1 has a property named "ID".
I use a datagrid from the WPFToolkit and bind to this collection.
Within the datagrid is a combobox column and I bind it's ItemsSource to the ID property of the class.
At this point, all is good and everything populates as it should. What I want to do is modify the ObservableCollection to reflect the value selected in the ComboBox.
I have a ValueConverter bound to the SelectedItemBinding on the ComboBox as follows:
SelectedItemBinding="{Binding Path=ID, Converter={StaticResource IDConverter}}
What is the best (i.e: WPF approved method) of modifying the collection? When the IDConverter ConvertBack() method is called, I get the appropriate Class1 instance, but I can't access the Observable collection from within the ValueConverter and I also don't have access to the SelectedIndex value from the Datagrid.
I could create a class as a static resource with a pointer to my collection and pass that as a ConverterParameter, but that seems sort of hokey and I'm assuming there must be some slicker way of doing this with databinding.
For the record, a simple solution is to create a local resource with a reference to the collection you wish to modify as a dependency property. You can then pass this as a ConverterParameter and have access to it in the ConvertBack() interface method.
A caveat: You will most likely encounter a DeferRefresh exception when you make changes to the collection and then you lose focus.
An excellent fix is found here:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/187b2b8f-d403-4bf3-97ad-7f93b4385cdf

Silverlight: Listbox bind to CollectionViewSource\List update on remove of item

I have a Listbox that I binds to a resource (sort) CollectionViewSource in my XAML. Then in my cs code I set the CollectionViewSource source to List of objects (class level field)
I then have "remove button" that checks the selected items in the Listbox and removes them from the List of objects (class level field).
I thought the Listbox should update automatically since the items source updated.
Am I missing a step or property setting ?
Or am I missing something about how binding works?
tep
The class that contains your list of objects must implement INotifyPropertyChanged and you must raise the notification event when the list changes, passing in the name of the property that changed. This is what notifies the UI that it must update anything bound to that property.
Alternatively, make your collection of objects an ObservableCollection<T> and that will do the notifying for you.

How do I loop through a set of items in a databound Silverlight control such as the ListBox?

I have a silverlight ListBox that has it's ItemsSource set. From the C# code behind I want to loop through each ListBox item and change the value of the text and access controls that are in the ListBox ItemTemplate. How would I do that?
ListBox controls in silverlight are bound to an ienumerable type, so that if any value in the ListBox changes, the underlying data is changed and vice versa depending on what type of binding you require. To effectively iterate the items you'll want to iterate through the enumerable object you've bound to.
You can get to the collection by accessing the ListBox.ItemsSource property and change the text of appropriate items, perform LINQqueries etc. If you have bound the controls correctly, saving the collection should update the list.
Hope this helps!

How do I BringToView the latest item added to a bound ObservableCollection

I have a silverlight control (View) which displays a list of items in a specified property of the datacontext (viewmodel).
What I need is for the scrollviewer in my control to scroll to the top or bottom depending on where the latest item has been added to the list. (It'll always be either the beginning or the end of the list, I don't need to worry about middle of list insertions.)
In WPF i'd just use the DataContextChanged event to start listening to the viewmodel, but in silverlight that event is internal.
Any ideas on how to tackle this?
A good starting point is Attached Behaviors on CodeProject.
A useful behavior would watch the ListBox.ItemsSource and attach to the observable collection when set. On the collection changed event, use ListBox.ScrollIntoView to display the changed item.
I can't use the CollectionChangedEvent of ObservableCollection since I need the DataContextChanged event to get the DataContext which holds the Collection in the first place.
Would you not do this in the ViewModel?
Whatever ViewModel has the ObservableCollection, expose a property of type T named SelectedItem and whenever the ObservableCollection changes with a new item, the CollectionChanged event will allow you to set the SelectedItem property. Once this is done, wire up the SelectedItem in the control to this property on your ViewModel.
This will obviously only work with controls like ListBox where a SelectedItem property exists.
In place of DataContextChanged in WPF , you can use CollectionChanged event of ObservableCollection. In the collection changed you will get to know the NewItem Index.

Resources