12

I've got a main WPF window:

<Window x:Class="NorthwindInterface.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:NorthwindInterface.ViewModels" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <ViewModels:MainViewModel />
    </Window.DataContext>
    <ListView ItemsSource="{Binding Path=Customers}">

    </ListView>
</Window>

And the MainViewModel is this:

class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public MainViewModel()
    {
        Console.WriteLine("test");
        using (NorthwindEntities northwindEntities = new NorthwindEntities())
        {
            this.Customers = (from c in northwindEntities.Customers
                              select c).ToList();
        }
    }

    public List<Customer> Customers { get;private  set; }

Now the problem is that in designermode I can't see my MainViewModel, it highlights it saying that it can't create an instance of the MainViewModel. It is connecting to a database. That is why (when I comment the code the problem is solved).

But I don't want that. Any solutions on best practices around this?

And why does this work when working with MVVM:

    /// <summary>
    /// Initializes a new instance of the <see cref="MainViewModel"/> class.
    /// </summary>
    public MainViewModel()
    {
        // Just providing a default Uri to use here...
        this.Uri = new Uri("http://www.microsoft.com/feeds/msdn/en-us/rss.xml");
        this.LoadFeedCommand = new ActionCommand(() => this.Feed = Feed.Read(this.Uri), () => true);
        this.LoadFeedCommand.Execute(null); // Provide default set of behavior
    }

It even executes perfectly at design time.

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Anemoia
  • 7,928
  • 7
  • 46
  • 71

5 Answers5

15

If you want to set the DataContext in XAML, you can use this at the top of your ViewModel ctor:

if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
    return;
Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Kribensa
  • 379
  • 2
  • 9
7

What you could try is just setting the DataContext in the code behind and see if that resolves the issue. It is pretty much the exact same thing, but maybe your IDE is just playing up.

DataContext = new MainViewModel();
Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Richard
  • 3,207
  • 5
  • 30
  • 35
  • 1
    Actually, this is perfectly valid. MVVM != no code behind. MVVM == View concerns in the View. – Ben Von Handorf Mar 23 '10 at 09:44
  • 1
    MVVM doesn't state that the View isn't allowed to have any code in it. In fact, many of the top MVVM experts repeatedly say that if it will take you an hour to do something in XAML and 5 minutes to do in code, then do it in code, as long as the segregation from the View to the ViewModel isn't broken. So the above is very acceptable in MVVM. And works in my test :) – Richard Mar 23 '10 at 09:54
  • 1
    @Snake: *Because that is not done in the MVVM concept* - Religion is never useful good in software design. Aside from the fact that you are not correct in your statement, often times real world code does not fit perfectly into a given design pattern in its most strict definition. – Ed S. Mar 09 '11 at 18:59
  • 1
    Snake is right. It isn't that MVVM forbids code in the code behind files, rather that it proscribes minimizing the coupling between the view and viewmodel. Ideally the view should only know about the viewmodel through data binding and not be dependent on the concrete type of the viewmodel. Instantiating the concrete viewmodel in the view's code behind increases coupling. – Neutrino Mar 27 '13 at 13:41
6

This will allow you to see the designer.

public MainViewModel()
{
    if (!DesignerProperties.IsInDesignTool)
    {
      Console.WriteLine("test");
      using (NorthwindEntities northwindEntities = new NorthwindEntities())
      {
        this.Customers = (from c in northwindEntities.Customers
                          select c).ToList();
      }
    }
}
gary
  • 92
  • 1
  • 1
4

try this:

public MainViewModel()
{
    if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
    {
      Console.WriteLine("test");
      using (NorthwindEntities northwindEntities = new NorthwindEntities())
      {
        this.Customers = (from c in northwindEntities.Customers
                      select c).ToList();
      }
    }
}
Houdini Sutherland
  • 1,550
  • 21
  • 20
0

I have seen this error message when the ViewModel does not have a parameterless constructor.

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Ralf
  • 9
  • 1