4

我从 MVVM 开始,我开始理解事物。我目前正在尝试使用 Cinch 框架,尽管我还没有致力于它。
我通过在视图的代码隐藏中引用 ViewModel 将 ViewModels 注入到 Views 中,属性上有一个 [Dependency],并在 setter 中使用 Unity 将 DataContext 设置为正确的视图。巧妙的把戏,我想。

我试图让我的应用程序作为单个窗口工作,并注入视图(与多个窗口相反并处理打开\关闭它们)我将视图从 Windows 更改为 UserControls,并在主窗口中添加了一个。这行得通,但从未注入 ViewModel,大概是因为 XAML 不使用 Container.Resolve 创建视图,因为当我创建视图并使用 Resolve 在代码隐藏中手动添加时,创建了 [Dependency] .

如何设置我的窗口,以便如果我通过 XAML 添加视图,或者视图由于 UI 操作等而更改,它通过 Unity 获取它,以便它可以发挥它的魔力?

4

2 回答 2

4

这个问题通常使用 Regions 和 RegionManager 来解决。在主窗口 ViewModel 中,创建了一组区域并将其添加到 RegionManager。然后 ViewModels 可以被解析并添加到 Region.Views 集合中。

在 XAML 中,通常通过将 ItemsControl 的 ItemsSource 属性绑定到主 ViewModel 的 region 属性来注入 Region。

因此,在主屏幕 ViewModel 中,您将拥有如下内容:

    public class TestScreenViewModel
{
    public const string MainRegionKey = "TestScreenViewModel.MainRegion";

    public TestScreenViewModel(IUnityContainer container, IRegionManager regionManager)
    {
        this.MainRegion = new Region();
        regionManager.Regions.Add(MainRegionKey, this.MainRegion);
    }

    public Region MainRegion { get; set; }
}

这将在您的 IModule 中正常解决

        #region IModule Members

    public void Initialize()
    {
        RegisterViewsAndServices();

        var vm = Container.Resolve<SelectorViewModel>();
        var mainScreen = Container.Resolve<TestScreenViewModel>();
        mainScreen.MainRegion.Add(vm);

        var mainView = ContentManager.AddContentView("Test harness", mainScreen);
    }

    #endregion

你的模板的 XAML 表示看起来像

    <DataTemplate DataType="{x:Type TestModule:TestScreenViewModel}">
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
        <StackPanel>
            <ItemsControl ItemsSource="{Binding Path=MainRegion.Views}" />
        </StackPanel>
    </ScrollViewer>
</DataTemplate>
于 2009-11-16T14:02:30.600 回答
3

解决您的问题的方法是让您的窗口也有一个 ViewModel,并将 UserControls 的 ViewModels 作为属性公开。然后在您的窗口的 XAML 中,您只需使用绑定机制将 UserControl 的 DataContexts 绑定到您的主 ViewModel 的适当属性。并且由于该主 ViewModel 是从 Unity 容器中解析的,因此它会根据需要注入所有其他 ViewModel-s。

于 2009-11-15T02:32:49.713 回答