简体   繁体   English

这是在MVVM中使用ViewModelLocator的好方法

[英]Is this a good way of using ViewModelLocator in MVVM

WE have a ViewModelLocater class in our Silverlight App. 我们的Silverlight应用程序中有一个ViewModelLocater类。 It consist of a basic constructor and a public property to return the ViewModel for a class. 它由一个基本的构造函数和一个公共属性组成,以返回类的ViewModel。 The code is something like this 代码是这样的

public class ViewModelLocator
{
    private  Dictionary<string, ViewModel> _viewModels =
              new Dictionary<string, ViewModel>();

    public ViewModelLocator()
    {
        _viewModels.Add("Home",  HomeViewModel());
        _viewModels.Add("Setup", new SetupViewModel());
        _viewModels.Add("TasksActivities", new TasksActivitiesViewModel());
        _viewModels.Add("Timesheet", new TimesheetViewModel());
    }

    public ViewModel this[string viewName]
    {
        get { return _viewModels[viewName]; }
    }
}

and in each of the XAML pages we set the ViewModel for that page using 在每个XAML页面中,我们使用

DataContext="{Binding [Setup], Source={StaticResource ViewModelLocator}}"

Setup is the key in the above dictionary. Setup是以上字典中的键。

The Silverlight App is really big and we have only recently started looking into any memory leaks(There are many...) I am using Windbg to track these leaks and I have noticed a lot of memory leaks leading back to the ViewModelLocater class. Silverlight应用程序确实非常大,我们直到最近才开始调查任何内存泄漏(有很多...)。我正在使用Windbg跟踪这些泄漏,并且我注意到很多内存泄漏导致了ViewModelLocater类。 Every time the app loads the ViewModelLocator constructor creates ViewModels for all the Views. 每次应用加载时,ViewModelLocator构造函数都会为所有View创建ViewModel。 So I am wondering if there is a better way of implementing the ViewModelLocator class. 所以我想知道是否有更好的方法来实现ViewModelLocator类。

We use ViewModelLoader/ViewModelLocator to provide both DesignTime as well as Runtime DataContexts. 我们使用ViewModelLoader / ViewModelLocator来提供DesignTime以及Runtime DataContexts。

ViewModelLocator Class ViewModelLocator类

public static class ViewModelLocator
{
    public static readonly DependencyProperty FactoryProperty = DependencyProperty.RegisterAttached("Factory",
        typeof (IViewModelFactory), typeof (ViewModelLocator),
        new FrameworkPropertyMetadata(null, PropertyChangedCallback));

    public static void SetFactory(DependencyObject dependencyObject, IViewModelFactory value)
    {
        dependencyObject.SetValue(FactoryProperty, value);
    }

    public static IViewModelFactory GetFactory(DependencyObject dependencyObject)
    {
        return (IViewModelFactory) dependencyObject.GetValue(FactoryProperty);
    }

    private static void PropertyChangedCallback(DependencyObject dependencyObject,
        DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var fe = dependencyObject as FrameworkElement;
        if (fe != null)
        {
            fe.DataContext = GetFactory(dependencyObject).Create();
        }
    }
}

IViewModelFactory IViewModelFactory

public interface IViewModelFactory
{
    object Create();
}

ViewModelFactory ViewModelFactory

public class MainViewModelFactory : ViewModelFactoryBase
{
    protected override object CreateDesignTimeViewModel()
    {
        return new MainViewModel(new DesignTimeEventAggregator(), new DesignTimeLogger(), new ViewModelViewRepository());
    }

    protected override object CreateViewModel()
    {
        return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
}

ViewModelFactoryBase Class ViewModelFactoryBase类

public abstract class ViewModelFactoryBase : IViewModelFactory
{
    protected abstract object CreateDesignTimeViewModel();

    protected abstract object CreateViewModel();

    public object Create()
    {
        return Designer.IsInDesignTime() ? CreateDesignTimeViewModel() : CreateViewModel();
    }
}

And in XAML, this is how I hookup ViewModel Locator to View: 在XAML中,这就是我将ViewModel Locator连接到View的方式:

<viewModelLocation:ViewModelLocator.Factory>
    <viewModelFactories:MainViewModelFactory />
</viewModelLocation:ViewModelLocator.Factory>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM