WPF TreeView Selected Item and showing User Controls - c#

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 :)

Related

Setup code for WPF control created in xaml

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.

Update DataTemplate for a specific item on a listbox on Windows Phone 8 C#

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.

How to bind a grid to a user control

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.

Replacing ItemsControl ContentPresenter entirely with control being rendered

i'm using an ItemsControl to generate a list of controls based on my model.
When looking at the visual tree, i noticed that each of the rendered control is wrapped in a ContentPresenter. The controls that are added are a 3rd party control and are designed to display a splitter between each control if they are siblings..this allows a user to size each control. For example the following will show a splitter between each of the controls at run time.
<StackPanel>
<3rdPartyControl />
<3rdPartyControl />
<3rdPartyControl />
</StackPanel>
When using an ItemsControl, each of the 3rdPartyControl are wrapped in a ContentPresenter, and thus no splitter is shown. I have tried various ways to try and solve this problem but unable to get this to work unless i write code behind to add each control rather than rely on Xaml.
Does anyone know of a way to replace the contentpresenter completely (in my case with 3rdpartyControl)?
Thanks
In order to replace the ContentPresenter you could derive from ItemsControl and override the GetContainerForItemOverride method to create a specialized container control.
ListBox for example overrides this method to create a ListBoxItem as container for a new item object.
That's true, every element that you add to ItemsControl is wrapped with ContentPresenter, you can find more details about it in the greate series of articles from dr.wpf ItemsControl a-z
One way I would suggest to try is to change ItemsControl to ListBox and make ListBox act like ItemsControl. In this case you can re-style/re-template ListBoxItem and replace ContentPresenter with your control. You would also need to stop selection support. Here is ListBox style that you need to change.

WPF: DataBinding a ListBox where each item is a Tab Stop

I just built a WPF form that contains a ListBox. The ListBox has bound to it a list of TextBox controls. I need to make each TextBox control a TabStop so that a user can hit tab, type in a number, hit tab again and type in the next number, etc.
Problem is, the ListBox itself catches the tab then the next tab skips to following control after the ListBox.
Is there a way to make each TextBox inside the ListBox be tabbable (or perhaps another type of databound control that would work)?
Thanks
Well we don't really have enough information to answer the question (this depends on what Templates and Style the ListBox is using) but you'll potentially need to play with the KeyboardNavigation.TabNavigation property to change how to cycle through the items and set IsTabStop on the ListBox to false.
Something like:
<ListBox DataSource={Binding} IsTabStop="False" KeyboardNavigation.TabNavigation="Cycle" />

Categories