Unity & WPF - 通过属性注入将 DataContext 注入子控件

2024-01-31

我遵循 Jason Dollinger 的 MVVM 示例Lab49 http://blog.lab49.com/archives/2650了解将 Unity 与 MVVM WPF 应用程序结合使用的基础知识。我按照他的基本架构构建了一个简单的示例,使用属性注入和 Dependency 属性将视图模型注入到视图中。我的示例有一个主窗口,其中包含在窗口的 XAML 中创建的子用户控件。子控件(以及主窗口)有一个用于分配视图模型的属性:

[Dependency]
public IChildViewModel VM
{
    set { this.DataContext = value;}
}

我将所有内容连接到 app.xaml.cs 中:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    IUnityContainer container = new UnityContainer();

    container.RegisterType<IWindowViewModel, Window1ViewModel>();
    container.RegisterType<IChildViewModel, UserControl1ViewModel>();

    Window1 window = container.Resolve<Window1>();
    window.Show();
}

主窗口正在注入其视图模型,但子控件没有。有没有直接的方法可以将分辨率传播到子控件中?为此,我需要进行哪些架构更改?目前我还没有与 Unity 结合,所以如果支持这种行为,我可以更改为另一个容器。


答案取决于主窗口是否“拥有”子窗口作为复合视图,或者它动态创建新视图(对于模态或非模态子窗口)。

在第一种情况下,主 ViewModel 必须直接拥有子 ViewModel,这意味着您可以将子 ViewModel 实现为主 ViewModel 上的只读属性,并使用数据绑定将子 View 绑定到适当的属性。

您是否想让主 ViewModel 直接控制子视图的创建,或者使用以下命令将它们注入到其中:构造函数注入取决于您需要的可变性程度。

与往常一样,如果您需要在任意时间创建子视图的新实例,则注入抽象工厂是一个更好的模型。


举个例子,我经常定义这个接口并将其注入到需要它的 ViewModel 中:

public interface IWindow
{
    void Close();

    IWindow CreateChild(object viewModel);

    void Show();

    bool? ShowDialog();
}

这允许 ViewModel 创建新窗口并显示它们(例如作为对话框)。一个简单的实现如下所示:

public class WindowAdapter : IWindow
{
    private readonly Window window;

    public WindowAdapter(Window window)
    {
        if (window == null)
        {
            throw new ArgumentNullException("window");
        }

        this.window = window;
    }

    #region IWindow Members

    public void Close()
    {
        this.window.Close();
    }

    public IWindow CreateChild(object viewModel)
    {
        var cw = new ContentWindow();
        cw.Owner = this.window;
        cw.WindowStartupLocation = WindowStartupLocation.CenterOwner;
        cw.DataContext = viewModel;
        return cw;
    }

    public void Show()
    {
        this.window.Show();
    }

    public bool? ShowDialog()
    {
        return this.window.ShowDialog();
    }

    #endregion
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity & WPF - 通过属性注入将 DataContext 注入子控件 的相关文章

随机推荐