2

I'm trying to get my head around WPF, Unity and MvvMlight (galasoft). So far my little set up works. If I run my application the label is filled with a random name generated by my DataService. (small victory getting all moving parts to work)

But in the design view of Visual Studio the label remains empty. How do i convince VisualStudio to render some 'design time' data in my label?

I'm using: Visual Studio Premium 2013, Unity 4.0.1, MvvmLight 5.2, .net 4.5

App.xaml.cs

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IDataService, DataService>();
        container.RegisterType<IMainViewModel, MainViewModel>();

        MainWindow mainWindow = container.Resolve<MainWindow>();
        mainWindow.Show(); 

        base.OnStartup(e);
    }
}

In App.xaml I have not defined the StartUpUri

MainWindow.xaml

<Window x:Class="UnityMvvmTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="500">
    <Grid>
        <Label x:Name="myLabel" Content="{Binding MyText}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public MainWindow(IMainViewModel theViewModel)
        : this()
    {
        this.DataContext = theViewModel;
    }
}

MainViewModel.cs

public class MainViewModel : ViewModelBase, IMainViewModel
{
    private readonly IDataService _dataService;

    public MainViewModel(IDataService dataService)
    {
        _dataService = dataService;

        if (IsInDesignMode)
        {
            // Code runs in design time data.
            MyText = "Design Data";
        }
        else
        {
            // Code runs "for real"
            MyText = _dataService.GetName();
        }

    }

    public string MyText { get; set; }
}
Dribbel
  • 2,060
  • 2
  • 17
  • 29

1 Answers1

0

I found a method, using hints from https://stackoverflow.com/a/3380895/249845

I created a second (flat) implementation of IMainVieModel in a separate namespace: UnityMvvmTest.ViewModel.Design. This implementation has no logic, it just fills the properties so the designer has some data to display.

This implementation is used in design time, since it is specified as the DesignTime DataContext. (with xmlns:d, xmlns:mc and xmlns:vm). The mc-namespace is needed to hide the d-namespace during runtime, see why.

The result is 5 extra lines in the Xaml, an extra (almost empty) implementation of IMainViewModel. And an extra (empty) constructor in code behind, instead of a constuctor that test for IsInDesignMode. This isn't a big deal, since unity will pick the constructor with the most parameters it can resolve.

MainWindow.xaml

<Window x:Class="UnityMvvmTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:UnityMvvmTest.ViewModel.Design"
    d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type=vm:MainViewModel}"
    mc:Ignorable="d"
    >
    <Grid>
        <Label x:Name="myLabel" Content="{Binding MyText}" />
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    // Contructor used in DesignTime
    public MainWindow()
    {
        InitializeComponent();
    }

    //Constructor used by Unity
    public MainWindow(IMainViewModel theViewModel)
        : this()
    {
        this.DataContext = theViewModel;
    }
}

MainViewModel.cs (design time implementation)

namespace UnityMvvmTest.ViewModel.Design
{
    public class MainViewModel : IMainViewModel
    {

        public MainViewModel()
        {
            MyText = "my Design time data";
        } 

        public string MyText { get; set; }
    }
}
Community
  • 1
  • 1
Dribbel
  • 2,060
  • 2
  • 17
  • 29