Hi I implemented something I asked in a thread here WPF MVVM Master detail view with a datagrid and a TabControl
It is a master details view with a datagrid as master and TabControl as child view. The SelectedItem of the grid is bound to the ItemsSource of the TabControl.
How can I access the Item bound to the TabControl in the Command written in the viewmodel? Basically I want to add new item in the bound collection (to child). But the bound item is the selectedItem of the datagrid - how do I find which one it is.
It would help to have some detail about the command you're trying to get to work, but you should be able to bind the CommandParameter on whatever control you're using to the same DataGrid.SelectedItem property that you're using for the TabControl's ItemsSource. That CommandParameter should then be available to you as a parameter into your command handler (might look different depending on what ICommand implementation you're using - DelegateCommand, RelayCommand, etc).
Do not wire the controls directly together but introduce some kind of a proxy property in your viewmodel that both controls bind to. One of them with Mode=TwoWay.
You can use CollectionViewSource.GetDefaultView() to return the ICollectionView that the TabControl is bound to. If you set IsSynchronizedWithCurrentItem to true on the TabControl then the ICollectionView's Current property will be what you can pass in to your command
You need a property in your ViewModel called SelectedCause . Bind the SelectedItem property for your DataGrid to this SelectedCause Property. Then, instead of binding the TabControl to SelectedItem.Solutions, bind that to SelectCause.Solutions . It's better to do it this way precisely because of the problem you are having. You need a property in your ViewModel that represents the currently selected Cause. The ViewModel is meant to be a representation of the state of the View. The selected item in the DataGrid is part of that state, so you should have a SelectedCause property in your ViewModel.
Related
My View (V) is bound to a ViewModel (VM). In the V I have a List of objects that is displayed in a ListView. In the ListView I use an ItemTemplate, each item is displayed as a Label holding the name of the item and a Combobox with the SelectedItem set to another property of the item. The Combobox is bound to a List which is also part of the VM of the main V (I bind it using ElementName=ListBox.DataContext in the Binding...)
So far everything works very well. The problem is that the Combobox can contain a lot of entries and I would like to use grouping or filtering. I know how to use filtering and grouping using ListCollectionView. But I cannot simply change my List to a ListCollectionView since it is used multiple times (for each item in the ListView). One ListCollectionView cannot be used multiple times but have different SelectedItem for each usage.
Now I am looking for an easy way to use grouping in the ListView's Combobox.
Is there a way to define the ListCollectionView directly in XAML inside the ItemTemplate (DataTemplate)? I also thought about using a (non-shared) Converter in the ItemsSource Binding that converts my List of objects into a ListCollectionView (if I use OneTime Binding, the Converter will only be called once, is that correct?)? I know I could also put each object in the List in the VM in its own ViewModel and each of it provides its own ListCollectionView for the Combobox, but that seems to be the most complicated solution (but maybe the cleanest?)
Any other suggestions or advice?
If you want to use the same ICollectionView in multiple comboboxes (or other selectors) without synchronizing their selected item, you need to explicitely set IsSynchronizedWithCurrentItem="False" on each combobox.
I have a ListBox bound to a list of ViewModel objects on the LHS of my screen. The ListBox.SlectedItem is bound to a property on my "MainWindowViewModel", called CurrentItem. On the RHS I have a large area that displays the selected item in detail, containing many nested controls for editing and browsing the information the ViewModel contains.
There are two approaches to building the view that I am aware of.
The large area on the RHS is a ContentPresenter with the Content property bound to CurrentItem. In my resources, define a template to be used with my ViewModel object.
The large area on the RHS is a fixed UserControl containing all the required xaml to display the my ViewModel. I bind the DataContext property of my UserControl to CurrentItem.
Which is the nicer approach and why? Perhaps option 2 is better in general but option 1 could be used when there are view models of different types in the ListBox, each with their own template?
Personally I would not bind directly to the selected Object in the ViewModel because doing that you are breaking the MVVM Pattern.
What I would suggest to do is to create a ViewModel for the whole view Including your list of ViewModels and adding a SelectedViewModel Property that is bound to the selected item. So the selection infromation is also in the ViewModel.
Then you can bind the SelectedObject of the "parent" ViewModel to the RHS.
I would suggest reading this MSDN Article for an introduction how to display SelectedItems using the MVVM Pattern.
I want to create a settings menu that looks similar to VLC's advanced settings menu: Treeview on the left and some kind of control collection on the right. The controls on the right should enable the user to manipulate settings that are relevant to the current selection in the tree view. I thought about creating a grid right of the tree view. Then I have a user control for each view that needs to be displayed in the grid, based on the selection
The item in the treeview has a UserControl property that holds a reference to the relevant view. My viewmodel has a SelectedItem property that indicates which item in the tree view is currently selected.
Now I want to bind the content of the grid to the UserControl property of my SelectedItem. But I cannot figure out how to do that. I would prefer to use a XAML based solution instead of clearing the Children property of the grid and adding the user control that I want to display in code each time the SelectedItem property changes.
I'd suggest using ContentControl instead of Grid.
Considering the tree view and the content control are under the same view model: on your view model, add property for selected item (let's call it VMSelectedItem) of same type as the items in the tree view.
In XAML of the tree view add
SelectedItem="{Binding VMSelectedItem}"
In XAML of the content control
Content="{Binding VMSelectedItem.UserControl}"
Now selection in the tree will update the VMSelectedItem property that, in turn, will update the content of the content control.
I suggest you using DataTemplates that you have declared inside your resouces dictionay. You would be using only one instance of each DataTemplate which leaves nice memory footprints. You wouldnt need to store instance of view inside your viewmodel which is the basic idea of mvvm. The viewmodel would completely just holding data and information how you wish the data to be displayed.
As example you have an enum inside your viewmodel with values person, car, tree. Inside your DataTemplateSelector you will have an if on that enum that returns what the desired DataTemplate.
Basically you would have everything central instead of having everything per each TreeViewItem.
I have an ObservableCollection of items of class X. I have a user control to show to the user the information inside X. How can I create the binding so the user controls are created when data is added to the ObservableCollection?
Thanks.
Use and ItemsControl with an ItemTemplate containging the UserControl. Bind or set the ItemsSource to your collection.
See this reference for examples and in-depth explanaitions.
I have created a Treeview in WPF MVVM (Project is using MVVM Light).
When I add a data to a DataTemplate of the Treeview, I want to reload the entire treeview. For this I am sending a Message from my data entry viewmodel to my treeview view model.
Though the message is recieved, the tree doesnt get refreshed. I called LoadChildren on each node again, and used RaisePropertyChanged as well but the data didnt get updated.
The TreeView is bound to a hierarchical collection in your ViewModel, and it has a property name, e.g. TreeViewData. Assuming your ViewModel implements INotifyPropertyChanged, simply call the PropertyChanged handler for property TreeViewData. This will completely refresh the TreeView.
My answer is based on the fact you are using Mvvm light, since you did not provide code I will just state the obvious and it might solve your issues.
Is your viewmodel implementing the ViewModelBase interface? (which implements INotifiedPropertyChanged)
I never used TreeViews but assuming it's using a collection as its datatemplate, you have to call RaisePropertyChanged on the collection whenever you add/remove an item and also whenever an item changes. Calling RaisePropertyChanged only in the "set" of the collection won't be enough.