Соединение вложенного представления для просмотра модели в Prism 4.0 и MEF - PullRequest
3 голосов
/ 06 декабря 2010

Я новичок в MEF и пытаюсь понять, как структурировать мое приложение Prism 4.0 для соединения представлений с представлениями моделей.Мой пример использования - один пользовательский элемент управления вложен в другой пользовательский элемент управления.Я хотел бы подключить вложенный пользовательский элемент управления к его модели представления.Я пытался следовать примерам Prism 4.0, но не уверен, что использую лучшие практики MEF.

Вот несколько фрагментов из моего приложения, чтобы продемонстрировать проблему.HomeView имеет вложенный пользовательский элемент управления под названием HelloView.Мне нужно подключить HelloView к его модели представления под названием HelloViewModel.Код в его текущем состоянии не работает.Я думаю, что HelloView не создается MEF и, следовательно, HelloViewModel не подключается.

***** HomeModule *****
[ModuleExport(typeof(HomeModule))]
public class HomeModule : IModule
{
    IRegionManager _regionManager;

    [ImportingConstructor]
    public HomeModule(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public void Initialize()
    {
        // Create the view
        IHomeView homeView = ServiceLocator.Current.GetInstance<IHomeView>();

        // Add it to the region
        IRegion region = _regionManager.Regions["MainRegion"];
        region.Add(homeView, "HomeView");
        region.Activate(homeView);
    }
}


****** IHomeView *****
public interface IHomeView
{
}


***** HomeView.xaml *****
<UserControl ...>

    <Grid x:Name="LayoutRoot">
        <view:HelloView x:Name="helloView"/>
    </Grid>

</UserControl>


***** HomeView.xaml.cs *****
[Export(typeof(IHomeView))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class HomeView : UserControl, IHomeView
{
    public HomeView()
    {
        InitializeComponent();
    }
}


***** IHelloView *****
public interface IHelloView
{
}


***** HelloView.xaml *****
<UserControl ...>
    <StackPanel x:Name="LayoutRoot" Margin="10">
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
            <TextBlock Text="Name" VerticalAlignment="Center" />
            <TextBox Width="100" VerticalAlignment="Center" Margin="10 0 0 0"
                     Text="{Binding Path=Name, Mode=TwoWay}" />
            <Button Content="Submit" VerticalAlignment="Center" Margin="10 0 0 0"
                    Command="{Binding SubmitCommand}"/>
        </StackPanel>
        <TextBlock Text="{Binding Message}" Margin="0 10 0 0" Foreground="Red" />
    </StackPanel>
</UserControl>

***** HelloView.xaml.cs *****
[Export(typeof(IHelloView))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class HelloView : UserControl, IHelloView
{
    public HelloView()
    {
        InitializeComponent();
    }

    [Import]
    public IHelloViewModel ViewModel
    {
        set { this.DataContext = value; }
    }
}


***** IHelloViewModel *****
public interface IHelloViewModel
{
}


***** HelloViewModel *****
[Export(typeof(IHelloViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HelloViewModel : NotificationObject, IHelloViewModel
{
    public HelloViewModel()
    {
        this.SubmitCommand = new DelegateCommand<object>(this.OnSubmit);
    }

    private void OnSubmit(object obj)
    {
        Message = "Hello " + Name;
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (value != _name)
            {
                _name = value;
                this.RaisePropertyChanged("Name");
            }
        }
    }

    private string _message;
    public string Message
    {
        get { return _message; }
        set
        {
            if (value != _message)
            {
                _message = value;
                this.RaisePropertyChanged("Message");
            }
        }
    }

    public ICommand SubmitCommand { get; private set; }
}

1 Ответ

1 голос
/ 07 декабря 2010

Ваше решение в порядке, у меня есть только 2 примечания: Первое: если ваш каталог содержит более 1 типа IHelloViewModel (это, скорее всего, потому что у вас есть несколько представлений и моделей представления соответственно), тогда вы получите ошибку композиции, потому что импорт возвращает большечем один результат.

[Import]public IHelloViewModel ViewModel

должно быть что-то вроде

[Import(typeof(HelloViewModel))] IHelloViewModel ViewModel

или вы просто создаете свою собственность как:

   [Import]
public HelloViewModel ViewModel

Второе: не используйте ServiceLocator для созданиявашего HomeView.ServiceLocator предназначен для создания одноэлементных экземпляров, а EventAggregator является идеальным кандидатом для этого.Представления не должны быть общими (и вы правильно пометили его как [PartCreationPolicy(CreationPolicy.NonShared)] - в противном случае, если вы хотите добавить свое представление в другой регион, вы получите ошибку.))

use

   [Import]
    public HomeView HomeView 

Hopeэто помогает.

...