Как передать ViewModel конструктору UserControl, который отображается в ContentPresenter?

У меня есть несколько пользовательских элементов управления, которые должны отображать одни и те же данные. Каждый UserControl имеет различный макет данных, которые должны быть представлены. ContentPresenter может привязаться к любому из UserControls, используя DataTemplate в моих ресурсах и привязав Content к StyleViewModel. Каждый UserControl связан с ViewModel, как определено в DataType DataTemplate. Все ViewModels, связанные с любым заданным UserControl, наследуются от StyleViewModel. UserControls должны получать свои данные из SettingsViewModel. Пользовательские элементы управления отображаются в главном окне.

Проблема в том, что я не могу понять, как сделать данные из SettingsViewModel доступными для UserControls.

Можно ли передать ссылку на SettingsViewModel в конструктор одного из этих пользовательских элементов управления, которые отображаются с помощью ContentPresenter?

Есть ли другой способ легко переключаться между различными представлениями данных (например, моими пользовательскими элементами управления) без использования ContentPresenter? Если да, то как мне сделать данные доступными для UserControls?

Ниже приведен код из моего SingleLineViewModel.cs:

public class SingleLineViewModel : StyleViewModel
{
    public SingleLineViewModel() { }
}

Другие ViewModels аналогичны. По сути, это пустые классы, которые наследуются от StyleViewModel, поэтому я могу привязываться к свойству Style, имеющему тип StyleViewModel, в моей SettingsViewModel. StyleViewModel также является практически пустым классом, наследуемым от ViewModelBase.

Ниже приведен код из моего Resources.xaml:

<ResourceDictionary <!--other code here-->
                    xmlns:vm="clr-namespace:MyProject.ViewModel"
                    <!--other code here-->
    <DataTemplate DataType="{x:Type vm:SingleLineViewModel}">
        <vw:ucSingleLine/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:SeparateLinesViewModel}">
        <vw:ucSeparateLines/>
    </DataTemplate>
    <!--other code here-->
</ResourceDictionary>

Ниже приведен код из SettingsViewModel.cs:

public class SettingsViewModel : ViewModelBase
{
    // other code here        
    private StyleViewModel _style;
    public StyleViewModel Style
    {
        get { return _style; }
        set
        {
            if (value != _style && value != null)
            {
                _style = value;
                OnPropertyChanged("Style");
            }
        }
    }
    // other code here
    public SettingsViewModel()
    {
        _style = new SingleLineViewModel();
    }
    // other code here
}

Ниже приведен код из моего MainView.xaml:

<ContentPresenter Name="MainContent" Content="{Binding SettingsVM.Style}"/>

person Jackson Dean Goodwin    schedule 01.01.2013    source источник
comment
ViewModels обычно передаются через свойство DataContext представления. Стилизация обычно выполняется через DynamicResource и загружается путем слияния свободного стиля XAML в ResourceDictionaries приложения.   -  person Danny Varod    schedule 01.01.2013


Ответы (1)


Вы можете обнаружить, что пытаетесь сделать много одновременно. Подумайте, как вы могли бы протестировать этот сценарий? Или как бы вы прошлись по данным в отладчике, чтобы проверить его состояние? Хорошая практика рекомендует, чтобы ваши данные были отделены от ваших элементов пользовательского интерфейса. Шаблон MVVM, который вы пытаетесь использовать, обычно предоставляет модели представления, чтобы помочь перевести данные из простых данных в формы, которые может использовать пользовательский интерфейс. Имея это в виду, я бы рекомендовал вам попытаться разработать уровень ViewModel, который представляет все данные без пользовательского интерфейса, удерживающего их вместе, то есть вместо того, чтобы пытаться внедрить дополнительные SettingsViewModel в ваши элементы управления, вы должны сделать так, чтобы ваши модели просмотра содержали все, что им нужно.

Похоже, у вас хорошее начало, ваша модель SettingsViewModel позволяет вам получить стиль, но ваш стиль, похоже, не содержит никаких данных. Так почему бы не передать его в конструкторе.

public SettingsViewModel()
{
    _style = new SingleLineViewModel(WhatINeedForStyle);
}
person AlSki    schedule 01.01.2013