cryodream
cryodream

Reputation: 311

Caliburn.Micro multiple views via View.Context doesn't work

I want to use multiple views for the same viewmodel. I can't seem to work it out. What am I doing wrong? The simple example:

The file viewmodel:

using System.IO;

namespace WpfApplicationExample.MVVM
{
    internal class FileViewModel
    {
        public FileInfo FileInfo { get; set; }
    }
}

The file list viewmodel:

namespace WpfApplicationExample.MVVM
{
    class FileListViewModel
    {
        public FileViewModel Files { get; set; }
    }
}

The file list view. This is where I try to use View.Context, but it doesn't work:

<UserControl x:Class="WpfApplicationExample.MVVM.FileListView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:cal="http://www.caliburnproject.org"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <ListView Name="Files" cal:View.Context="Details"/>
    </Grid>
</UserControl>

The file view #1: Details:

<UserControl x:Class="WpfApplicationExample.MVVM.File.Details"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Orientation="Horizontal">
        <Label Name="FileInfo_Name"/>
        <Label Name="FileInfo_Length"/>
        <Label Name="FileInfo_Directory"/>
    </StackPanel>
</UserControl>

The file view #2, Simple:

<UserControl x:Class="WpfApplicationExample.MVVM.File.Simple"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Label Name="FileInfo_Name"/>
    </Grid>
</UserControl>

This is just a most basic idea, to show file placement and where I'm trying to put the cal:View.Context="Details"

So why it's not working?


Edit: I'm sorry, I thought I made the question easy to understand, it seems, not. Let me elaborate:

The situation I'm describing is very simple. The easiest example is Windows File Explorer. You know, how you can easily change the views: Details, List, Tiles, Small Icons, Large Icons, etc... That's it - you are displaying the same folder's content, the same file list, hence we assume, the same single viewmodel. The only thing that changes is the view that is used to display that same viewmodel. Details view, List view, etc. Same single viewmodel. Multiple different views.

Taken from Caliburn.Micro documentaion:

  1. View / View Model Naming Conventions · Caliburn.Micro
    Section: Naming Convention for Multi-View Support
    As mentioned in the Conventions section of the documentation, the framework was designed to handle a one-to-many relationship between ViewModel and View.

  2. Screens, Conductors and Composition · Caliburn.Micro
    Section: Multiple Views over the Same ViewModel
    You may not be aware of this, but Caliburn.Micro can display multiple Views over the same ViewModel. This is supported by setting the View.Context attached property on the View/ViewModel’s injection site.

I hope this helps to clear things up.

Upvotes: 0

Views: 2500

Answers (2)

Nigel Sampson
Nigel Sampson

Reputation: 10609

The View.Context needs to be placed on the ContentControl where the view is being injected, for the case of a ListView you'd need to modify the ItemTemplate.

<ListView.ItemTemplate>
    <DataTemplate>
        <ContentControl cm:View.Model="{Binding}" cm:View.Context="Details" />
    </DataTemplate>
</ListView.ItemTemplate>

Upvotes: 1

mvermef
mvermef

Reputation: 3924

Yes view switching... <ContentControl x:Name="SomePropertyName" cm:View.Context="Details" /> Don't believe I have ever seen it on a ListView. Since the idea is you are switching out the view. Normally done with <ContentControl cm:View.Context="{Binding CurrentView}" cm:View.Model="{Binding}" />, where CurrentView is something you switch in your viewmodel in question, folder structure will come into play here. First place it will look is in a subfolder in the ViewModel folder ViewModels -> Main would correspond to MainViewModel.

What you have there won't work since the idea for view switching would have to be a datatemplate in the case above. since you are trying to change the actual lay out of the ListView. View switching is not going to be the best solution in this case.

A lot of times those things are changed in listview with a templateselector

Upvotes: 0

Related Questions