2013-11-20 2 views
0

У нас есть класс ViewModelLocater в нашем приложении Silverlight. Он состоит из базового конструктора и публичного свойства для возврата ViewModel для класса. Код что-то вроде этогоЭто хороший способ использования ViewModelLocator в MVVM

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]; } 
    } 
} 

и в каждой из страниц XAML мы устанавливаем ViewModel для этой страницы, используя

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

Setup является ключевым в вышеуказанном словаре.

Приложение Silverlight действительно очень велико, и мы только недавно начали изучать любые утечки памяти (их много ...) Я использую Windbg для отслеживания этих утечек, и я заметил много утечек памяти, ведущих к Класс ViewModelLocater. Каждый раз, когда приложение загружает конструктор ViewModelLocator, создается ViewModels для всех представлений. Поэтому мне интересно, есть ли лучший способ реализации класса ViewModelLocator.

+0

Вы можете не создавать ViewModels лениво (как и в случае необходимости), вместо того чтобы создавать все заранее ? – sthotakura

+0

Класс ViewModelLocater был создан, чтобы дать фиктивную модель для времени разработки. Каждое представление создает новый экземпляр их viewmodel в их событии OnNavigatedTo. Теперь я новичок в MVVM и Silverlight, и этот класс ViewModellocater был создан предыдущим старшим программистом. поэтому я не уверен, что это правильный способ его создать. –

+0

Мы используем ViewModelLoader/ViewModelLocator для предоставления как DesignTime, так и Runtime DataContexts. Наш код ViewModelLoader будет выглядеть как [this] (http://ebook-management.googlecode.com/svn/trunk/SourcesProject/eLibraryCatel/eLibraryCatel/Factory/ViewModelLoader.cs), и все наши ViewModelFactories будут реализовывать [IFactory] (http: //ebook-management.googlecode.com/svn/trunk/SourcesProject/eLibraryCatel/eLibraryCatel/Factory/IFactory.cs). Таким образом, вы создаете ViewModels только по мере необходимости, а не все из них заранее. – sthotakura

ответ

1

Мы используем ViewModelLoader/ViewModelLocator для предоставления как DesignTime, так и Runtime DataContexts.

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

public interface IViewModelFactory 
{ 
    object Create(); 
} 

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 Класс

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

    protected abstract object CreateViewModel(); 

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

И в XAML, это как я Подвод ViewModel локатор Вид:

<viewModelLocation:ViewModelLocator.Factory> 
    <viewModelFactories:MainViewModelFactory /> 
</viewModelLocation:ViewModelLocator.Factory> 
Смежные вопросы