繁体   English   中英

如何在Prism / MEF中的ItemsControl中对视图进行排序?

[英]How to sort views in an ItemsControl in Prism / MEF?

我用prism v4和MEF来加载我的模块。 我的模块包含一些视图(MVVM),它们由MEF自动加载到ItemsControl / NavigationRegion中。

这很好用,所有项目都显示在ItemControl中。 但我不喜欢他们表现的顺序。 一个模块可能包含多个项目,因此更改模块加载顺序本身是不够的。

如何在ItemsControl中对不同的视图进行排序? 是否有办法按某些财产对它们进行排序?

由于StockTraderRI示例中的属性,我使用棱镜V4,MEF和探索。

这实际上是Prism4的结果。 只需将ViewSortHintAttribute应用于您的视图:

[ViewSortHint("100")]
class FirstView : UserControl { }

[ViewSortHint("200")]
class SecondView : UserControl { }

区域上的默认排序比较器将获取此属性并相应地对视图进行排序。 您可以将任何字符串放入属性中,但我倾向于使用中等大小的数字,这使我可以轻松地在现有的数字之间添加新视图。

哦宕,这比我想象的更简单的方法

您可以告诉区域经理如何对特定区域中的视图进行排序。 您只需要为该地区提供比较功能。

这个例子按一个非常愚蠢的值排序,函数名称:

private static int CompareViews(object x, object y)
{
  return String.Compare(x.ToString(), y.ToString());
}

this._regionManager.Regions["MyRegion"].SortComparison = CompareViews;

当然,在设置SortComparison之前,区域管理员需要知道该区域。 到目前为止,我发现实现此目的的唯一解决方法是推迟使用Dispatcher设置比较函数:

private readonly IRegionManager _regionManager;

[ImportingConstructor]
public ShellViewModel(IRegionManager regionManager)
{
  this._regionManager = regionManager;
  Dispatcher dp = Dispatcher.CurrentDispatcher;
  dp.BeginInvoke(DispatcherPriority.ApplicationIdle, new ThreadStart(delegate
  {
    if (this._regionManager.Regions.ContainsRegionWithName("MyRegion"))
      this._regionManager.Regions["MyRegion"].SortComparison = CompareViews;
  }));
}

当然,应该使用一些比排序顺序的类名更有用的信息,但这应该很容易解决(我只是为所有可能添加到该区域的视图添加一个接口,提供一个值来排序)。

我很确定你正在寻找CollectionViewSource Bea提供了有关如何在链接中使用它的一些信息。

从MVVM的立场来看,这就是我在ViewModel中使用ICollectionView _scriptService.Scripts属性是一个ObservableCollection<T>被包装在ICollectionView ,并返回给View。 _view.Filter用于过滤ICollection中的项目,从而更改View。 类似于输入'acc'并查看列表中以'acc'开头的所有项目。

    public class ScriptRepositoryViewModel : AViewModel
    {
        private readonly IUnityContainer _container;
        private readonly IScriptService _scriptService;
        private readonly IEventAggregator _eventAggregator;

        private ICollectionView _view;

        public ScriptRepositoryViewModel(IUnityContainer container, IScriptService scriptService, IEventAggregator eventAggregator)
        {
            _container = container;
            _scriptService = scriptService;
            _eventAggregator = eventAggregator;
        }

        public ICollectionView Scripts
        {
            get 
            {
                if (_view == null)
                {
                    _view = CollectionViewSource.GetDefaultView(_scriptService.Scripts);
                    _view.Filter = Filter;
                }

                return _view;
            }
        }
     }

下面是负责过滤的代码,它通过Prism中的DelegateCommand进入,它驻留在同一个ViewModel中。

#region SearchCommand
public DelegateCommand<object> SearchCommand { get; private set; }

private String _search = String.Empty;
private void Search(object commandArg)
{
    _search = commandArg as String;
    _view.Refresh();
}

public bool Filter(object arg)
{
    bool usingPrefix;

    IScript script = arg as IScript;
    if (script.FileType == ConvertPrefixToFileType(_search, out usingPrefix))
    {
        if (_search.Length == 2)
            return true;
        else
            return CheckProperties(script, usingPrefix);
    }
    else
    {
        if (usingPrefix)
            return false;
        else
            return CheckProperties(script, usingPrefix);
    }
}

有了基本功能并使用ICollectionView您可以按如下方式应用排序....

_view.SortDescriptions.Add(new SortDescription("PropertyName", direction));

有关排序行为的更多信息可以在这里找到,因为要记住一些性能想法。

您可以使用元数据或属性。 这取决于你是否可以控制界面......

视图按添加顺序显示:

RegionManager.RegisterViewWithRegion("ListRegion", typeof(ListView));
RegionManager.RegisterViewWithRegion("ListRegion", typeof(ListView2));
RegionManager.RegisterViewWithRegion("ListRegion", typeof(ListView3));

看起来像:

---- region-- | | view3 | | view2 | | 查看|


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM