Silverlight MVVM MEF ViewInjection - PullRequest
2 голосов
/ 04 марта 2010

, поскольку мой заголовок соответствует модным словам, я надеюсь, что получу много ответов на мой вопрос или указатели в правильном направлении.

Хорошо, я обычно использую ViewModel, который содержит список ViewModels.

public class MasterViewModel
{
    public ObservableCollection<DetailViewModel> DetailViewModels { get; set; }
    public DetailViewModel Detail { get; set; }
}

   <ItemsControl ItemsSource="{Binding DetailViewModels}">
        <ItemsControl>
            <ItemsPanelTemplate>
                <StackPanel />
            </ItemsPanelTemplate>
        </ItemsControl>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <views:DetailsView />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Имея это в виду, теперь я перейду к моим вопросам. Я прочитал много хорошего о MEF, а также увидел образец приборной панели Glenn Block, но это не помогло мне достаточно.

То, что я хочу сделать, это sidbar (например, боковая панель windows). Боковая панель = StackPanel ListItems = Гаджет

Но я хочу это в стиле MVVM

ОК, у меня есть что-то вроде контракта

IGadget

Я реализовал пользовательский экспорт.

[ExportGadget(GadgetType = GadgetTypes.News)]

У меня есть NewsGadgetView.xaml (который реализует IGadget), и он импортирует NewsGadgetViewModel, а также делает себя доступным как ExportGadget.

пока все хорошо. С этим я могу создать набор гаджетов.

Тогда у меня есть мой SidbarView.xaml, который импортирует sidebarViewModel.

и теперь я заблудился ...

Я подумал о чем-то вроде GadgetFactory, который использует PartCreator для создания моих гаджетов. но это будет сидеть в моем SidebarView.xaml Но я хочу контролировать свои гаджеты, чтобы добавлять и удалять их с боковой панели. Итак, я подумал о чем-то вроде ObserveableCollection ...

Который я связываю с

GadgetHost - это Grid, который будет динамически загружать гаджет ....

Так как мне создать свою боковую панель, содержащую различные гаджеты, не зная, какие гаджеты доступны, и иметь ViewModel для боковой панели, а также для каждого гаджета? ...

Спасибо за любую помощь ....

1 Ответ

2 голосов
/ 05 марта 2010

Вот тут-то и проявляется мощь Managed Extensibility Framework. У меня в принципе та же проблема с существующим проектом.

Я решил абстрагировать виды и регионы, а затем использовать механизм маршрутизации.

По сути, существует специальный экспорт для региона, и я экспортирую FrameworkElement (может быть, StackPanel, Grid и т. Д.). Представления имеют набор атрибутов, которые экспортируются как UserControl.

Менеджер обрабатывает импорт с помощью отложенной коллекции импорта. Он просто присваивает их словарю, поэтому у нас есть сопоставления перечислений видов с экземплярами представлений, а затем сопоставление перечислений регионов с экземплярами регионов.

Затем таблица маршрутов ожидает запроса на активацию вида (это может произойти при загрузке), находит маршрут от вида к региону и вставляет его.

А как насчет модели вида?

Для «глобальной» информации я использую экспортируемый контракт, например:

[Export(typeof(IMasterViewModel))]
public class MasterViewModel 
{
}

Это имеет то, что может понадобиться каждому плагину. Затем у меня есть базовая модель представления, от которой наследуются модели «дочернего» представления:

public class BaseViewModel 
{
   [Import(typeof(IMasterViewModel))]
   public MasterViewModel MasterVM { get; set; }
}

Итак, давайте представим, что у меня совершенно отдельный XAP. Мне нужно будет ссылаться на некоторые "общие" интерфейсы. Так что я не ссылаюсь на экземпляр модели глобального представления, просто на контракт. Тем не менее, в моем плагине XAP, я могу сделать это:

[Export]
public class PluginViewModel : BaseViewModel 
{
   etc ... etc .. 
}

public partial class PluginControl : UserControl 
{
    [Import]
    public PluginViewModel 
    {
        get { return LayoutRoot.DataContext as PluginViewModel; }
        set { LayoutRoot.DataContext = value; 
    }
}

Когда модель вида импортируется в вид, она также импортирует модель основного вида, предоставляя доступ к этим другим частям. Если вам нужно инициировать какое-либо действие, когда модель представления доступна, просто реализуйте IPartImportsSatisfiedNotification, и вы можете запустить, когда будете готовы.

...