在Prism 4.0和MEF中连接嵌套视图到视图模型

3
我是一个MEF的新手,正在尝试弄清楚如何构建我的Prism 4.0应用程序以连接视图和视图模型。我的用例是在一个用户控件中嵌套另一个用户控件。我想将嵌套的用户控件连接到其视图模型。我尝试遵循Prism 4.0示例,但不确定是否使用了最佳实践。
以下是我的应用程序的一些片段,以演示问题。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

你的解决方案是可以的,我只有两个注意事项: 第一:如果你的目录包含多种类型的IHelloViewModel(这很可能是因为你有几个视图和相应的视图模型),那么当导入返回多个结果时,你会得到一个组合错误。

[Import]public IHelloViewModel ViewModel

应该是类似这样的

[Import(typeof(HelloViewModel))] IHelloViewModel ViewModel

或者你可以将你的属性定义为:

   [Import]
public HelloViewModel ViewModel

第二点: 不要使用ServiceLocator来创建您的HomeViewServiceLocator旨在创建单例实例,而EventAggregator是完美的候选人。视图不应该被共享(并且您正确地将其标记为[PartCreationPolicy(CreationPolicy.NonShared)] - 否则,如果您想将视图添加到另一个区域,则会出现错误。)
使用
   [Import]
    public HomeView HomeView 

希望这能有所帮助。

谢谢grimcoder!好的提示。我认为我的原始帖子没有清楚表明代码实际上并不起作用 - HelloView没有与HelloViewModel建立连接。我猜想HelloView的构建没有通过MEF。最佳方法是什么来完成这个连接? - Naresh
从你的代码中我看不出为什么你的ViewModel属性没有被捕获,你的代码是不完整的 - 缺少IHelloViewModel。 此外,PRISM建议在Module Initialise()方法中进行View/ViewModel关联。 - grimcoder
我已经在原始帖子中添加了IHelloViewModel代码 - 它只是一个空接口。我希望MEF能够更自动地连接视图和视图模型(而不是在模块初始化方法中手动创建它们)。 - Naresh
@Naresh:使用MEF实现这一点的唯一方法是在您的视图构造函数中导入IHelloViewModel并将其分配给视图的数据上下文。 这将使您的视图模型和视图耦合在一起,但通常情况下都是如此。 - Anderson Imes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接