I want to achieve the following hierarchical navigation model in a WPF MVVM application:
ShellView
Page1View
Subpage1View
Subpage2View
Subpage3View
Page2View
...
Meaning that on Shellview, I have buttons to activate/deactivate Page1View and Page2View. On Page1View has buttons to activate Subpage1View and Subpage3View and Subpage1View has a button to activate Subpage2View.
Where should the subpages be displayed ? Should the navigational model map to a view structure exacly ? I mean, I have a ContentControl (named ActiveItem) on ShellView, where Page1View and Page2View is displayed when activated. Should the Subpage1View be displayed on Shell's ActiveItem ContentControl or on the parent view (Page1View) ?
If I should display a subpage on ShellView, then how to activate it properly ? Because the button to activate it is on Page1View not on shell.
If I should display a subpage on the parent view (Page1View), then I must create a ActiveItem ContentControl on Page1View and hide it before it's needed. How ? Also I guess parent view scrollbars could become a problem.
Please advise!
Using Caliburn.Micro 1.3, .NET 4, WPF.
Thanks!
I threw a demo together. I'm not sure if it's exactly what you're looking for. The thing to remember is Screens and Conductors can contain Screens and/or Conductors. So nesting or doing complex screen composition is pretty straight forward.
This example has a ShellView with 2 buttons and a ContentControl. Page1ViewModel also has 2 buttons and a ContentControl.
Clicking Page1 or the Page2 button on the ShellView activates the appropriate Page. The same is true once a Page is activated, clicking on SubPage1 or SubPage2 activates the appropriate SubPage.
https://bitbucket.org/dbeattie/cmwpfnavsample/src
We use sub pages this way:
Subpage itself is shown in a ContentControl that is in page view. So we have shell view that has a ContentControl to show active page and in this active page, there is another ContentControl to show Active sub page.
We show list of current page's subpages on the shell view itself (because of layout), so we have ItemsControl that is bound to ActiveItem.Items (provided the ActiveItem is page inherited from Conductor).
So we simply use ItemsControl to choose which page or subpage is the currently active and then use ContentControl to show it. Note that selected subpage is shown through its parent page view.
But basically, it is up to you whether you show subpages directly on shell view (ContentControl bound to ActiveItem.ActiveItem) or use another way.
Although subpages are not included, Coproject sample application might help you. I plan to make it more complex and add subpages later.
ad 2. I don't think you need to hide the ContentControl -if no subpage is selected, it will be empty. Nevertheless, if you want to hide it, I'd suggest using of ValueConverter (from object to Visibility, if object == null then Visibility.Collapsed, otherwise Visible) and bind the ActiveItem ContentControl's Visibility property to ActiveItem again.
Related
For an error validation mechanism, I've to be able to "navigate" in my application to one specific pane.
Currently I've one "SelectedNode" and tries to focus the control that is bound to this property(basically, I've an AttachedProperty to set the IsFocus, based on the name).
My issue is that sometimes this page contains tabs. And it appears that the control cannot be focused if it's hidden(not in the active tab).
Is there a way from an UserControl to go up in its visual tree to "activate" all his parent?
I cannot just bind the "SelectedIndex" of my tabcontrol in the viewModel, for a lot of reasons:
The UserControl that has the tab has one sub user control for each tab, so the usercontrol doesn't know what is in which usercontrol
Putting such things in the ViewModel is wrong, the ViewModel should not have to know that it's displayed in tabs or all in the same pane
Thanks!
I have two WPF forms (MainWindow and ChildWindow) with their different viewModels already in place (MainViewModel and ChildViewModel) to manage the events.
When I click the menu item on MainWindow to open the ChildWindow, I want a specific button to be hidden in the ChildWindow.
How can I perform this using MVVM?
On the child window's VM
Put a Boolean property (with the change notification as with other properties on the VM) which when true will show the button and false hide it.
On the button's Visibility property bind to the VM property and use a Boolean to visibility converter (has one already been defined in the page's resource, of so use it) to take the true/false value and change it to a visibility value.
This article doesn't get into the full blown history of MVVM, but it provides a basic example to help you with MVVM and binding:
Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding
I have a simple window with two buttons on bottom, when one button is clicked it change the view model of my main window, the name of the content button and the command.
I would like that when user click on the button change this with a loading user control i already have but i'm stacked, i don't know it's something i can implement with xaml or i need some code on my view model.
Any suggestions would be appreciated.
Thanks.
You will need some code on your ViewModel to swap out the Button for the Loading control. You can either do this with binding ContentControls or with a Boolean property to set one to visible and the other to hidden while the loading happens.
I am building an application which has an ItemsControl, and my DataTemplate for this contains a ContentPresenter. I am binding this ContentPresenter to a UserControl property of my ViewModel. I would like to be able to allow the user to click a button on the UserControl which then shows that UserControl in a new popup window, and then when closed, it reverts back to being in the ItemsControl.
I can get this to show the UserControl in the popup window no problems, but have no idea how to revert it back to being in the ItemsControl.
Any suggestions for this approach would be greatly appreciated.
thanks
Put simply you should not keep a UserControl (a UI element) inside your "ViewModel". Your ViewModels should hold the State of your UI and not the UI itself. Define two different UserControls for the two parts you want it in but this time Bind them to the same ViewModel properties.
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.