question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

I have a ViewModel without View

See original GitHub issue

I am using Caliburn.Micro to build WPF PC program, which is a great framework. But recently I have a problem:  I have a ViewModel that does not require a View. It’s actually a navigation, through the TabControl Items switch to the specified website.  I have browsed: View.cs, ConventionManager.cs, ViewLocator, ViewModelLocator, can not solve my distress. Can not find view for … always exists.  Can I only create an empty view to solve this problem? Or can Caliburn.Micro provide such a switch to let me control?

AppBootstrapper:

`

namespace Caliburn.Micro.Test.WPF
{
  using System;
  using System.IO;
  using System.Windows;
  using System.Collections.Generic;
  using System.ComponentModel.Composition;
  using System.ComponentModel.Composition.Hosting;
  using System.ComponentModel.Composition.Primitives;
  using System.Linq;
  using Caliburn.Micro;

  public class AppBootstrapper : BootstrapperBase
  {

     private CompositionContainer container;

    public AppBootstrapper()
    {
        Initialize();
    }

    protected override void Configure()
    {
        var catalog = new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
        var batch = new CompositionBatch();
        var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");

        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);

        catalog.Catalogs.Add(new DirectoryCatalog(path));
        container = new CompositionContainer(catalog);

        batch.AddExportedValue(container);
        batch.AddExportedValue<IWindowManager>(new WindowManager());

        batch.AddExportedValue<IEventAggregator>(new EventAggregator());
        batch.AddExportedValue(catalog);

        container.Compose(batch);
    }

    protected override void BuildUp(object instance)
    {
        base.BuildUp(instance);
    }

    protected override object GetInstance(Type service, string key)
    {
        var contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
        var exports = this.container.GetExportedValues<object>(contract);

        if (exports.Any())
        {
            return exports.First();
        }

        throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return this.container.GetExportedValues<object>(AttributedModelServices.GetContractName(service));
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        DisplayRootViewFor<IShell>();
    }
}

}

`

ShellViewModel `

namespace Caliburn.Micro.Test.WPF.ViewModels
{
  using System;
  using System.Collections.Generic;
  using System.ComponentModel.Composition;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;

  [Export(typeof(IShell))]
  internal class ShellViewModel : Conductor<INavigation>.Collection.OneActive, IShell
  {
      [ImportingConstructor]
      public ShellViewModel([ImportMany]IEnumerable<INavigation> tabs)
      {
          Items.AddRange(tabs.OrderBy(x => x.Index));
          DisplayName = "WPF.Test";
      }
     
      public void NavigationChanged(SelectionChangedEventArgs e)
      {
        var tab = e.OriginalSource as TabControl;
        var nav = tab.SelectedItem as INavigation;
  
        if (nav == null)
            return;

        tab.SelectedIndex = nav.Redirect((e.RemovedItems[0] as INavigation).Index);
      }
  }
}

`

ShellView

<TabControl Name="Items" cal:Message.Attach="[Event SelectionChanged] = [Action NavigationChanged($eventArgs)]" />

INavigation `

public interface INavigation
{
    string Icon { get; set; }

    int Index { get; set; }

    int Redirect(int index);
}

`

BuyProductViewModel `

namespace Caliburn.Micro.Test.WPF.ViewModels
{
    [Export(typeof(INavigation))]
    internal class BuyProducts : Screen, INavigation
    {
        public string Icon { get; set; }

        public int Index { get; set; }

        public int Redirect(int index)
        {
           // System.Diagnostics.Process.Start("https://www.google.com/?p=BuyProduct");
            return Index;
        }

      public BuyProducts()
      {
          DisplayName = "Buy Product";
          Index = 0;
      }
  }
}

`

MoreProductsViewModel `

namespace Caliburn.Micro.Test.WPF.ViewModels
{
    [Export(typeof(INavigation))]
    internal class MoreProducts: Screen, INavigation
    {
        public string Icon { get; set; }

        public int Index { get; set; }

        public int Redirect(int index)
        {
           // System.Diagnostics.Process.Start("https://www.google.com/?p=More Products");
            return Index;
        }

      public MoreProducts()
      {
          DisplayName = "More Products";
          Index = 0;
      }
  }
}

`

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
nigel-sampsoncommented, Sep 17, 2017

To be honest this is the first time it’s ever come up as a requirement.

0reactions
kaysonwucommented, Sep 16, 2017

I thought the CM would have a switch that would allow me to omit the creation of an empty view file…

Read more comments on GitHub >

github_iconTop Results From Across the Web

A viewmodel without a view, can it be justified?
In MVVM, ViewModels must be independant of Views . So, YES, a Viewmodel can be without a View .
Read more >
View Model Doesn't Have To Depend on ViewModel
View Model Doesn't Have To Depend on ViewModel · ViewModel is an abstract class. No one likes extending abstract classes without a good...
Read more >
Do we need Models if we are using ViewModels?
The ViewModel must under no circumstances access those tables. So yes, you can have a ViewModel with those fields. But that view model...
Read more >
How to Use Model-View-ViewModel on Android Like a Pro
My goal in this article is to explain why the Model-View-ViewModel architectural pattern presents a very awkward separation of concerns in ...
Read more >
Model-View-ViewModel (MVVM)
The app UI can be redesigned without touching the view model and model code, provided that the view is implemented entirely in XAML...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found