How do I stop my ViewModel code from running in th

2019-02-08 08:20发布

问题:

I'm developing a networked WPF application with the MVVM pattern and it seems that it's running and connecting to servers in the designer.

I know about the IsInDesignMode property, but I'm not sure how to access it in a ViewModel.

回答1:

DependencyObject dep = new DependencyObject();
if (DesignerProperties.GetIsInDesignMode(dep))
{
    ...
}


回答2:

Just to add to these suggestions, you probably want to optimize for production deployment.

If you need to check the design mode in the ViewModel, you should only do so when in DEBUG mode, otherwise the released version will always have to perform unnecessary checks.
When developing, if in design mode you can exit the method (or even stub out some fake data).

Put this code as the first line of your constructor (or whatever code is being called):

C#:

#if DEBUG
    if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) return;
#endif

VB:

#If DEBUG Then
    If DesignerProperties.GetIsInDesignMode(New DependencyObject()) Then Return
#End If


回答3:

I thought I'll add to this as I've just looked up something I spotted in VS2015 and it provides an alternative solution. In the designer there is a button to "Disable project code".

I'm making the assumption that your ViewModel is being instantiated and doing stuff from your code behind. I know it breaks pure MVVM, but I've seen plenty of people do stuff like DataContext = new MyViewModel(); within the constructor in the code behind.

Toggling this button should solve that issue and helps to keep your code cleaner. Checkout MSDN for more information.

Here's the image from the MSDN documentation so you know what it looks like. I'm sure the link will break eventually, anyway.

I spotted this in VS2015, but not sure which edition this feature was added.

As a side note, it also doubles up as a nice way to reload the designer. Albeit a slow one when I tried. Your milage may vary.



回答4:

I use the following statement around code that I can only execute at application runtime and would otherwise cause an exception in the XAML designer.

      if (System.Windows.Application.Current.MainWindow != null)


回答5:

Put a design time data source in your XAML like this:

<UserControl x:Class="Company.Product.View.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" 
xmlns:vm="clr-namespace:Company.Product.ViewModel.Design"
xmlns:design_vm="clr-namespace:Company.Product.ViewModel.Design"
mc:Ignorable="d" Name="MyView">
<UserControl.Resources>
    <ObjectDataProvider ObjectType="{x:Type design_vm:MyViewModel}" x:Key="DesignTime_DataSource" d:IsDataSource="True"/>
</UserControl.Resources>
<Grid d:DataContext="{StaticResource DesignTime_DataSource}">
....
</Grid>
</UserControl>

Let your design time viewmodel inherit from the run time viewmodel, but mock up the data in the constructor. You may also have to do something to your run time view model so the design time viewmodel doesn't run the data access code.



回答6:

It all depends on how you set up the binding between the view and the view-model. If it's initiated by the view in the constructor (which seems likely given the symptoms), you can check IsInDesignMode from there. Otherwise you need to provide a very quick overview of your architecture (or framework if you use any).