11

I have a wpf application using Caliburn.Micro. I have a view MyView:

<UserControl x:Class="ReferenceMaintenanceWorkspace.MyView"
         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"
         >
  <UserControl.Resources>
 </UserControl.Resources>
 <TabControl x:Name="Items" > 
</TabControl>

I have also MyViewModel:

using System.ComponentModel.Composition;

namespace ReferenceMaintenanceWorkspace
{
[Export(typeof(MyViewModel))]
public class MyViewModel
{
  public MyViewModel()
  {
      base.DisplayName = "Reference Maintenance";
  }

Because of some reason, I get the following message on the tab control:

Cannot find view for ReferenceMaintenanceWorkspace.MyViewModel.

Could you please explain why this could happen? Thanks.

David Shochet
  • 5,035
  • 11
  • 57
  • 105

6 Answers6

17

Just for the future, it happens also after renaming classes/packages, but in view xaml file "x:Class" is not updated.

pmezykowski
  • 336
  • 2
  • 7
12

Caliburn Micro is expecting certain file structure within your project. Your views and viewmodels should be in separate folders named Views and ViewModels.

Here is a nice Hello World example that describes this.

ShadeOfGrey
  • 1,256
  • 12
  • 14
  • 1
    The application I am maintaining already had various views and viewmodels. None of them existed in folders with names Views and ViewModels, and yet they worked. They all existed in different class library projects though, and I am adding a new one called ReferenceMaintenanceWorkspace. I wonder if the projects should have some particular settings that I am not aware of... – David Shochet Jun 18 '12 at 13:06
  • 1
    Maybe it's being done manually Caliburn.Micro.View.SetModel(NameView, NameViewModel); – ShadeOfGrey Jun 18 '12 at 13:10
  • or in the View – ShadeOfGrey Jun 18 '12 at 13:14
  • No, such things are not used in the application. I tried it anyway, and it didn't help :( – David Shochet Jun 18 '12 at 13:22
  • Can you share the contents of the bootstrapper Configure method? Or the contents of IEnumerable SelectAssemblies() method (if it's there). – ShadeOfGrey Jun 18 '12 at 14:07
  • protected override IEnumerable SelectAssemblies() { var assyList = new List{System.Reflection.Assembly.GetExecutingAssembly()}; var dir = new DirectoryInfo("."); _workspaceAssyList = new List(); _workspaceAssyList.AddRange(dir.GetFiles("*Workspace.dll").Select(file => Assembly.LoadFile(file.FullName))); assyList.AddRange(_workspaceAssyList.ToArray()); return assyList } – David Shochet Jun 18 '12 at 14:16
  • I debugged this method, and could see my new project in assyList. – David Shochet Jun 18 '12 at 14:16
  • I'm kinda out of ideas :). One final shot in the dark. Is ViewLocator or ViewModelLocator used somewhere (if yes how)? – ShadeOfGrey Jun 18 '12 at 14:37
  • ViewLocator is used in one place, but it seems to have nothing to do with my problem, as that method is not called for other views that do work. – David Shochet Jun 18 '12 at 14:48
  • 1
    Figured it out. Instead of copying and pasting View and ViewModel files from another place, I created a brand new UserControl for the View and a class for the ViewModel... and it worked! I still don't know what the difference is though... – David Shochet Jun 20 '12 at 12:14
  • Glad you managed to getting done. If you ever find the root cause leave a message or create an answer, since this one is not really helpful :). – ShadeOfGrey Jun 21 '12 at 10:02
  • 1
    This "expecting certain file structure within your project" seems like a major limitation of Caliburn Micro to me. Surely the whole point of MVVM is to decouple the ViewModel and View, such that they can live in isolation from each other. With this model, not only are they tightly coupled, they are done so by "convention" rather than explicitly. – Stephen Holt Oct 17 '13 at 15:03
  • Thanks @ShadeOfGrey didn't know about the View.SetModel – juFo Jul 11 '17 at 08:11
  • The blog is no longer present. – Corey Oct 10 '19 at 21:17
  • Thanks @Corey Replaced with link from webarchive. – ShadeOfGrey Oct 11 '19 at 09:17
  • If you didn't add a window in views, that would not work. You should check the view in views folder. That should be the window or usercontrol. – DevCaf Jul 11 '20 at 02:08
8

You should override SelectAssemblies in bootstrapper and provide assembly name where your view lies in.

Sergii Shumakov
  • 116
  • 2
  • 4
4

make sure you have folders ViewModels and Views. Also make sure the names of your classes and usercontrols/windows also follow these namingconventions like:

  • = ViewModels
  • == YoloViewModel
  • = Views
  • == YoloView

If the views and viewmodels are located in a different assembly try this:

In your bootstrapper you need to add the assembly where the viewmodel/view is located:

protected override IEnumerable<Assembly> SelectAssemblies()
{
  var assemblies = base.SelectAssemblies().ToList();
  assemblies.Add(typeof(MyProject.Foo.ViewModels.YoloViewModel).Assembly);

  return assemblies;
}
juFo
  • 17,849
  • 10
  • 105
  • 142
1

I argee,I think fix this from two way. 1.In solution you should have two folders , one name is "Views" another is "ViewModels".

2.In your bootstrapper you need to add the assembly where the viewmodel or view is located:

protected override IEnumerable<Assembly> SelectAssemblies()
{
    var assemblies = base.SelectAssemblies().ToList();
    assemblies.Add(typeof(Project.ViewsNamespace.SomeView).Assembly);
   return assemblies;
}
leelds
  • 11
  • 2
0

Check for typo error. Mean If your ViewModel Class name is ShellViewModel.CS then Your View name should be ShellView. Typo erro might be in your ViewModel folder you have ShelViewModel.CS and in your View folder you have ShellView.CS.