There is an itemscontrol in one of my views that lets the user reorder the items by an up/down button.
My question is on how I can flow the current index of the items to my viewmodel
The following questions address on how to find the current index (not so clean but it does the job)
WPF - Bind to Item Index from within ItemTemplate of ItemsControl?
Now, how can I modify the XAML so that it binds this index to a property on my viewmodel?
edit The question is about how to do it in XAML declaratively. A possible solution is to do it in code using and ObservableCollection and subscribe to CollectionChanged
Kind Regards, Tom
So your items store an index poperty that you need to update when they are re-ordered in the UI?
I would create a view model that exposes my items as an ObservableCollection. You can then handle the CollectionChanged event which will fire when the items are re-ordered in your view model. At this point you can enumerate the collection of items updating their indices.
Related
I have a WPF window that has a datagrid and a user control for a form for the fields in that datagrid. The user control and the WPF window have view models.
The user control's DataContext is bound to one of the window's view model's member field, whose value changes during the data grid's Selection Changed event.
I'm not sure if this is the right way to do it because I am unable to create references from the inner view model to the outer view model for some reason. Constructor injection won't work because I'm required to use default constructor only, and I can't seem to put a property injector in the right place (always getting null reference when I try to use it).
I am also unable to get my property change notification to work properly in the inner view model.
Is there a better way to wire my view models so that they automatically change the values in the user control when a new row is selected in the datagrid? I have a feeling that binding to the control's DataContext is not the way to go.
This doesn't seems a complex/nested scenario. Looks like pretty much a normal master details scenario. Suppose you want to edit Customer data, I would have an ObservableCollection instance bind to the DataGrid, and there will be a SelectedCustomer property in the VM also. In the DataGrid you can set SelectedItem twoway bind to the SelectedCustomer property which makes SelectedCustomer always updated with your selection. Since the usercontrol has the same instance of customer as in the DataGrid row, whenever you change anything in the UC those data will get reflected in the grid. Ofcourse all those properties should fire NotifypropertyChanged.
I have a silverlight datagrid to which I am binding an observable collection from the viewmodel. There is a detail view page which will display different properties of the object in the collection when user selects a row of the datagrid. My requirement is when user updates any properties in the detail view; the data should be updated in the data grid also. How to implement this functionality?
Well, the answer is simply to bind both the datagrid row and the control displaying the selected object. The simplest way is to use a ICollectionView (returned by a CollectionViewSource from the original ObservableCollection), bind the grid's ItemsSource to that, and then bind the control's DataContext to the ICollectionView's CurrentItem. That way, when the grid's selected item changes, the CurrentItem of the ICollectionView is updated, and that item is displayed in the detail view.
I think it's quite easy but if you need additional details or sample source code I'll elaborate.
Calling OnPropertyChanged for an ObservableCollection only works when there has been some change to the properties of the collection, not the objects it contains (add, remove, clear, etc).
Is there any way to notify the View that there has been a change to an item within the collection?
The objects it contains have to implement INotifyPropertyChanged as well. In your setter you trigger the event, and WPF will pick up on this and read in the new value as long as you are using two-way bindings or read-only bindings.
I'm having difficulty correctly Data Binding my models in the view. I have a MainWindowViewModel which contains a list of AlbumViewModels. Each AlbumViewModel holds an AlbumModel. So I have multiple albums and I need to display information in an ObservableCollection in the AlbumModel. I have two ListBoxes. ListBox1 holds the list of AlbumViewModels that are in my MainWindowViewModel. My second ListBox I want to display the ObservableCollection from the current selected item from the AlbumViewModel.AlbumModel. How can I do this? I've tried binding the DataContext of ListBox2 to the ListBox1 element, along with SelectedItem as the path but that returns 'AlbumViewModel'. Is there anyway to bind ItemsSource of a ListBox to the binding of the DataContext, but in this case binding it to [DataContext].AlbumModel.ObservableCollection or something?
I apologise if it sounds rather complicated!
You can use the fact, that when you bind to a collection, WPF wraps collection to CollectionView. And this guy has CurrentItem.. Bea had good article: How can I sync selection of two data bound ListBoxes? and Dr.WPF is amazing (as usual): ItemsControl: 'C' is for Collection.
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.