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.
Related
Is it possible to see how a control created with XAML could be replicated with code behind? The reason I'm asking is that I would like to create a number of ListView controls based on each item in a Collection. My hope is that I can setup one ListView control in XAML and then somehow get the code that I would need to reproduce more Listview objects with the same settings in code-behind.
Alternatively; would it be possible to bind the Collection object containing all items that I want represented as ListView objects to any control that would then contain ListView controls for each item in the bound collection? Just the same way that a ListView can create ListViewItem controls if you bind a collection to the ListView control.
Cheers
Unless you have a very large hierarchy of controls, I recommend you to do it as follows: You create an List A which contains lists of your data, so A is List<List<Data>>
Then you create An Itemscontrol which is bound to this list. In the ItemTemplate, there is a ListView which its ItemsSource is bound to The DataContext.
I'm not being able to update a single item's DataTemplate on a list during runtime. In detail, here is what I'm trying to accomplish.
I have a Listbox where the items can have different states (Collapsed, expanded, disabled, etc), each with a different layout. I'm using a TemplateSelector to choose the correct DataTemplate according to a property on my class and that's working all great when I first create the list, the items are shown properly. However, when I change the property that sets the DataTemplate in runtime, the NotifyPropertyChanged is called and the information of the item is updated on the list, but not the DataTemplate. For example: I have a collapsed item with a label X that i want to expand. I click on the item and the label changes to Y but the DataTemplate doesn't update.
Any idea on how I can do this? Can't the DataTemplate be updated during runtime unless it is for the whole list?
I'll appreciate any help.
Make UserControl and use it inside your data template. Now, to change the state you can call methods on this UserControl and it will update. You can use animations via storyboard too.
I'm getting myself all in a pickle with TreeViews and User Controls; I'm fairly new to WPF so apologies in advance.
Synopsis
I have a collection of VM classes for my TreeView Items.
So the TreeView is bound to a collection of [Parent] VM instances, each of which has a collection of [Child]ren, and each [Child] has other data and other collections (which I won't bore you with).
The TreeView is on the left side of the form, and on the right I have a user control which should only be visible depending on the selected TreeViewItem type.
So, if the selected item of the TreeView is of '[Child]' type then the User Control should be visible.
Problem
I'm struggling with how to detect when an Item in the TreeView is selected so that I can show/hide the User control.
One way I thought of, but do not like, is to bind the 'IsSelected' property of the TreeViewItem to the [Child] VM class, then raise an event up to the main VM,
which would show/hide the UC via DP's. But this requires a whole load of Events etc and to me, just seems, messy.
Summary
For the life of me I cannot work out how to do this, I must be tired or something...or stupid...or both.
All I want to do is select an Item on the TreeView and the appropriate UserControl displays with the relevant data of the TreeViewItem, which I could in Windows Forms very easily, but obviously I'm not thinking about this in a very WPF'ish way at the moment.
Any links to articles etc appreciated.
Big up your chest for any responses.
In your case, i would prefer a DataTemplateSelector. It´s a object which provides a way to select a DataTemplate based on the databound object - here your ViewModel.
Just put a ContentControl in your Window and bind the Content-Property to the SelectedItem-Property of your TreeView. Set the ContentTemplateSelector-Property of the ContentControl to a reference of your own DataTemplate Selector.
The DataTemplateSelector will choose the correct DataTemplate with the defined UserControl by your requirements.
<DataTemplate x:key="VMParent">
<local:ParentUI DataContext="{Binding}" />
</DataTemplate/>
<DataTemplate x:key="VMChild">
<local:ChildUI DataContext="{Binding}" />
</DataTemplate/>
Greetings :)
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.
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.