我发现 Sam 的解决方案有效,但发现它在所有视图都已添加到该区域时执行排序,因此对视图进行了两次排序。
虽然它仍然是一个有效的解决方案,但阅读 Prism 讨论中的 this 帖子让我想到了一种在加载区域时、但在添加任何视图之前实现它的方法。
1 - 订阅 RegionChanged 集合
我将它放在 Shell ViewModel 代码中,该代码与包含我要排序的区域的视图相关联。每当解决 IRegionManager 导入时,我都会订阅其 Regions 集合的 CollectionChanged 事件:
this._regionManager.Regions.CollectionChanged +=
new NotifyCollectionChangedEventHandler(Regions_CollectionChanged);
2 - 更改事件委托中区域的 SortComparison
然后,每当 Regions 集合更新时,代理 Regions_CollectionChanged 就会执行,并将更改我所需区域的 SortComparison:
void Regions_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (var o in e.NewItems)
{
IRegion region = o as IRegion;
if (region != null && region.Name == RegionNames.NavigationRegion)
{
region.SortComparison = CompareNavigatorViews;
}
}
}
}
3 - 定义 CompareNavigatorViews 委托
在我的例子中,我只是按包含它们的程序集的标题对视图进行排序,您可以在此处实现自己的比较方法。请记住,您将在此处收到的对象是 View,而不是 ViewModel。
private static int CompareNavigatorViews(object x, object y)
{
if (x == null)
if (y == null)
return 0;
else
return -1;
else
if (y == null)
return 1;
else
{
AssemblyInfo xAssemblyInfo = new AssemblyInfo(Assembly.GetAssembly(x.GetType()));
AssemblyInfo yAssemblyInfo = new AssemblyInfo(Assembly.GetAssembly(y.GetType()));
return String.Compare(xAssemblyInfo.Title, yAssemblyInfo.Title);
}
}
以防万一有人问,AssemblyInfo 类是我制作的实用程序类。要获取程序集的标题,您可以使用此函数:
string GetAssemblyTitle(Assembly assembly)
{
object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length == 1)
{
return (attributes[0] as AssemblyTitleAttribute).Title;
}
else
{
// Return the assembly name if there is no title
return this.GetType().Assembly.GetName().Name;
}
}
希望这对某人有所帮助!