在这个帖子中:Can anybody provide any simple working example of the Conductor<T>.Collection.AllActive usage?我已经有了一部分答案,但我仍然很困惑。
我只想将我的所有视图模型引用到我的ShellViewModel中,以便能够打开/关闭ContentControls,但不会在构造函数中注入所有这些模型。
在答案中,建议在ShellViewModel的构造函数中注入一个接口。如果我这样做,我是否必须将所有ViewModel注入实现该接口的类中?
public MyViewModel(IMagicViewModelFactory factory)
{
FirstSubViewModel = factory.MagicallyGiveMeTheViewModelIWant();
SecondSubViewModel = factory.MagicallyGiveMeTheViewModelIWant();
ThirdSubViewModel = factory.MagicallyGiveMeTheViewModelIWant();
Items.Add(FirstSubViewModel);
Items.Add(SecondSubViewModel);
Items.Add(ThirdSubViewModel);
}
另外,我想避免通过IoC.Get&lt;&gt;为了获得我的视图模型的实例,我认为如果我没有弄错,它违反了IoC的原则。 在其他几个例子中,他们在需要时创建了新的viewModel,但在这种情况下使用IoC的重点是什么,特别是当我需要在这些新的ViewModel中注入服务时?
在我的Shell视图中,我有一个包含3个不同区域的布局,通过以下方式绑定到我的shell视图模型:
<ContentControl x:Name="Header"
Grid.ColumnSpan="3"/>
<ContentControl x:Name="Menu"
Grid.Row="1"/>
<ContentControl x:Name="Main"
Grid.ColumnSpan="3"/>
在我的ShellViewModel中扩展了Conductor.Collection.AllActive,我引用了这样的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);
}
我错过了一些明显的东西吗?
提前致谢!
答案 0 :(得分:0)
最后,我自己找到了答案。这一切都在AppBootstrapper中!
我最终为我的Screen创建了一个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作为param传递给我的ShellViewModel ctor:
IEnumerable<ViewModelBase> listScreens = GetAllScreenInstances();
container.Instance<IShell>(new ShellViewModel(listScreens));
然后将IShell传递给每个ViewModels
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);
}
希望这可以帮助将来的某个人!