我正在使用Prism编写WPF MVVM应用程序。几天前,我询问了管理不同观点的最佳实践,并没有得到很多反馈。感觉然后我想出了一个似乎有效的系统,但我想确保我不会在路上走。
我按照http://development-guides.silverbaylabs.org/上的教程来设置我的shell并确信我的模块注册良好。
但是,这些教程中没有任何地方是一个视图被替换为给定区域内的不同视图的示例。总的来说,这似乎很难找到一个很好的例子。所以,今天我推出了自己的问题解决方案。
本质上,模块有一个跟踪当前视图的控制器,然后当用户想要切换视图时,它调用Regions.Remove命令,然后使用add命令将其替换为当前视图。似乎必须有一个更优雅的解决方案,只需在不同的注册视图之间切换,但我还没有找到它。
初始化模块时,Unity容器会注册模块的所有不同可能视图。
控制器和视图切换功能如下:
namespace HazardModule
{
public class HazardController : IHazardController
{
private object CurrentView;
public IRegionManager RegionManager { get; set; }
private IUnityContainer _container;
public HazardController(IUnityContainer container)
{
_container = container;
}
/// <summary>
/// Switches the MainRegion view to a different view
/// </summary>
/// <typeparam name="T">The class of the view to switch to</typeparam>
public void SiwthToView<T>()
{
if (CurrentView != null)
{
RegionManager.Regions["MainRegion"].Remove(CurrentView);
}
CurrentView = _container.Resolve<T>();
RegionManager.Regions["MainRegion"].Add(CurrentView);
}
}
}
任何反馈或其他更好的解决方案都将受到赞赏。
答案 0 :(得分:1)
我的方法几乎相同,一个同样拥有Prism经验的同事也是如此。
基本上我有一个ViewController类,它是我的ViewModelBase类中的一个属性。这使我的所有ViewModel都可以一次访问它。然后在我的ViewController类中,我有一些显示管理方法。这种方法的正确性可能有争议,但我发现它在我的案例中运作良好
public TView ShowViewInRegion<TView>(string regionName, string viewName, bool removeAllViewsFromRegion)
{
var region = regionManager.Regions[regionName];
var view = region.GetView(viewName) ?? container.Resolve<TView>();
if (removeAllViewsFromRegion)
{
RemoveViewsFromRegion(region);
}
region.Add(view, viewName);
region.Activate(view);
if (regionName == RegionNames.OverlayRegion)
{
eventAggregator.GetEvent<PopupWindowVisibility>().Publish(true);
}
return (TView)view;
}
public void RemoveViewsFromRegion(string regionName)
{
RemoveViewsFromRegion(regionManager.Regions[regionName]);
}
private void RemoveViewsFromRegion(IRegion region)
{
for (int i = 0; i < region.Views.Count() + i; i++)
{
var view = region.Views.ElementAt(0);
region.Remove(view);
}
if (region.Name == RegionNames.OverlayRegion)
{
eventAggregator.GetEvent<PopupWindowVisibility>().Publish(false);
}
}
private static void DeactivateViewsInRegion(IRegion region)
{
for (var i = 0; i < region.ActiveViews.Count(); i++)
{
var view = region.ActiveViews.ElementAt(i);
region.Deactivate(view);
}
}
然后每当我需要切换视图或我可以从我的ViewModel调用的任何内容
public void ExecuteCreateUserCommand()
{
ViewController.ShowViewInRegion<IUserCreateView>(RegionNames.ContentRegion, ViewNames.UserCreateView, true);
}