连接嵌套视图以在Prism 4.0和MEF中查看模型

时间:2010-12-06 15:28:02

标签: prism mef

我是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 个答案:

答案 0 :(得分:1)

你的解决方案没问题,我只有2个笔记: 第一:如果你的目录包含多种类型的IHelloViewModel(很可能是因为你有相应的几个视图和视图模型),那么你会得到一个合成错误,因为import会返回多个结果。

[Import]public IHelloViewModel ViewModel

应该是

[Import(typeof(HelloViewModel))] IHelloViewModel ViewModel

或者您只需将您的财产设为:

   [Import]
public HelloViewModel ViewModel

第二:  不要使用ServiceLocator来创建HomeViewServiceLocator旨在创建单例实例,EventAggregator是完美的候选者。视图不应该被共享(并且您正确地将其标记为[PartCreationPolicy(CreationPolicy.NonShared)] - 否则您希望将视图添加到另一个区域以获得错误。) )

使用

   [Import]
    public HomeView HomeView 

希望这有帮助。