gpt4 book ai didi

mvvm - ShellViewModel Caliburn.Micro 中的 ViewModels 引用

转载 作者:行者123 更新时间:2023-12-03 10:43:47 26 4
gpt4 key购买 nike

在这个线程中:Can anybody provide any simple working example of the Conductor<T>.Collection.AllActive usage?我已经得到了部分答案,但我仍然很困惑。

我只想将我所有的 View 模型引用到我的 ShellViewModel 中,以便能够打开/关闭 ContentControls,但无需将它们全部注入(inject)构造函数中。

在回答中,建议在ShellViewModel的构造函数中注入(inject)一个接口(interface)。如果我这样做,我是否必须将所有 ViewModel 注入(inject)实现该接口(interface)的类中?

public MyViewModel(IMagicViewModelFactory factory)
{
FirstSubViewModel = factory.MagicallyGiveMeTheViewModelIWant();
SecondSubViewModel = factory.MagicallyGiveMeTheViewModelIWant();
ThirdSubViewModel = factory.MagicallyGiveMeTheViewModelIWant();

Items.Add(FirstSubViewModel);
Items.Add(SecondSubViewModel);
Items.Add(ThirdSubViewModel);
}

另外,我想避免通过 IoC.Get<> 来获取我的 View 模型的实例,如果我没记错的话,我认为它违反了 IoC 的原则。
在其他一些示例中,他们会在需要时创建新的 View 模型,但在这种情况下使用 IoC 有什么意义,尤其是当我需要在这些新 View 模型中注入(inject)服务时?

在我的 Shell View 中,我有一个包含 3 个不同区域的布局,通过以下方式绑定(bind)到我的 Shell View 模型:
 <ContentControl x:Name="Header"
Grid.ColumnSpan="3"/>
<ContentControl x:Name="Menu"
Grid.Row="1"/>
<ContentControl x:Name="Main"
Grid.ColumnSpan="3"/>

在我扩展 Conductor.Collection.AllActive 的 ShellViewModel 中,我引用了如下 3 个区域:
public Screen Menu { get; private set; }
public Screen Header { get; private set; }
public Screen Main { get; private set; }

我希望能够像这样更改它们:
Menu = Items.FirstOrDefault(x => x.DisplayName == "Menu");
Header = Items.FirstOrDefault(x => x.DisplayName == "Header");
Main = Items.FirstOrDefault(x => x.DisplayName == "Landing");

我所有的 ViewModel 在其构造函数中都设置了 DisplayName。

我试过了,但 GetChildren() 是空的
foreach (var screen in GetChildren())
{
Items.Add(screen);
}

我错过了一些明显的东西吗?

提前致谢!

最佳答案

最后,我自己设法找到了答案。这一切都在 AppBootstrapper 中!

我最终为我的屏幕创建了一个 ViewModelBase,以便它们都可以具有 IShell 属性(以便 ViewModel 可以触发 ShellViewModel 中的导航),如下所示:

public class ViewModelBase : Screen
{
private IShell _shell;

public IShell Shell
{
get { return _shell; }
set
{
_shell = value;
NotifyOfPropertyChange(() => Shell);
}
}
}

然后在 AppBoostrapper 中像这样注册它们:
container.Singleton<ViewModelBase, SomeViewModel>();
container.Singleton<ViewModelBase, AnotherViewModel>();
container.Singleton<ViewModelBase, YetAnotherViewModel>();

然后创建一个 IEnumerable 作为参数传递给我的 ShellViewModel ctor:
IEnumerable<ViewModelBase> listScreens = GetAllScreenInstances();

container.Instance<IShell>(new ShellViewModel(listScreens));

然后将 IShell 传递给每个 ViewModel
foreach (ViewModelBase screen in listScreens)
{
screen.Shell = GetShellViewModelInstance();
}

为了完整起见,这里是我的 GetAllScreenInstances() 和 GetShellViewModelInstance() :
protected IEnumerable<ViewModelBase> GetAllScreenInstances()
{
return container.GetAllInstances<ViewModelBase>();
}
protected IShell GetShellViewModelInstance()
{
var instance = container.GetInstance<IShell>();
if (instance != null)
return instance;

throw new InvalidOperationException("Could not locate any instances.");
}

这是我的 ShellViewModel ctor 的样子:
public ShellViewModel(IEnumerable<ViewModelBase> screens )
{
Items.AddRange(screens);
}

希望这可以帮助将来的人!

关于mvvm - ShellViewModel Caliburn.Micro 中的 ViewModels 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37882205/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com