繁体   English   中英

筛选多列ListView C#WPF

[英]Filter Multiple Columns ListView C# WPF

我想使用多列和多过滤器进行过滤以过滤我的ListView,但是我不知道如何...

在此处输入图片说明

这是我的想法:一个窗口显示当前选定的列标题,您可以在其中选择下拉列表中的=或>然后使用您的条件进行过滤,我只找到一列的解决方案,但对多重过滤器一无所知...

数据加载:

var xdoc = XDocument.Load(@"C:\temp\webTsl.xml");
                var units = from u in xdoc.Descendants("sl")
                            select new
                            {
                                EQNr = (string)u.Element("id"),
                                //EQCore = (string)u.Element(""),
                                ArtNr = (string)u.Element("artNr"),
                                Bez = (string)u.Element("bez"),
                                //KundenBez = (string)u.Element(""),
                                //ProjektNr = (string)u.Element(""),
                                //LiefDat = (DateTime)u.Element(""),
                                //EqStart = (DateTime)u.Element(""),
                                //GewaehrStart = (DateTime)u.Element(""),
                                //GewaehrEnde = (DateTime)u.Element("")
                            };

                foreach (var unit in units)
                {
                    items.Add(new Anlagen(unit.EQNr, unit.ArtNr, unit.Bez));
                }


            ListViewAnlagen.ItemsSource = CollectionViewSource.GetDefaultView(items); 

类:

 public virtual string EQNr { get; set; }
        //public virtual string EQCore { get; set; }
        public virtual string ArtNr { get; set; }
        public virtual string Bez { get; set; }
        //public virtual string KundenBez { get; set; }
        //public virtual string ProjektNr { get; set; }
        //public virtual DateTime? LiefDat { get; set; }
        //public virtual DateTime? EqStart { get; set; }


        //public virtual DateTime? GewaehrStart { get; set; }
        //public virtual DateTime? GewaehrEnde { get; set; }

        public Anlagen(string eqNr,string artNr, string bez) /*, DateTime liefdat, DateTime inbetnahme,DateTime garantiestart,DateTime garantieende*/
        {
            this.EQNr = eqNr;
            //this.EQCore = eqCore;
            this.ArtNr = artNr;
            this.Bez = bez;
            //this.KundenBez = kundenBez;
            //this.ProjektNr = projektNr;
            //this.LiefDat = liefDat;
            //this.EqStart = eqStart;
            //this.GewaehrStart = gewaehrStart;
            //this.GewaehrEnde = gewaehrEnde;

        }

        public Anlagen()
        {
    }

基本上,您需要一个过滤器定义,在其中传递您的项目,并且特定于列的过滤器函数确定该项目是否满足过滤器。

假设您有一个过滤器界面,如下所示:

public interface IFilterBase<TItem>
{
    PropertyInfo Property { get; } // can be used to display the property name etc.

    bool ApplyFilter(T value);
}

和一些实现

public class StringContainsFilter<TItem> : IFilterBase<TItem>
{
    public StringContainsFilter(PropertyInfo prop)
    {
        // TODO Requirements to check:
        // typeof(TItem).IsAssignableFrom(prop.DeclaringType)
        // typeof(string).IsAssignableFrom(prop.PropertyType)
    }

    // TODO Property getter implementation

    public string ContainedText { get; set; } // TODO INotifyPropertyChanged

    public bool ApplyFilter(TItem value)
    {
        // get the property value via reflection and check against the contains filter condition
        var text = Property.GetValue(value) as string ?? "";
        return text.Contains(ContainedText ?? "");
    }
}

当然,您必须为过滤中实际要支持的所有内容(属性类型和操作)定义过滤器实现。

因此,基本上,对于每一列,您都可以通过属性类型来决定支持的过滤器,然后让用户选择过滤器并输入条件。

剩下的问题是如何应用一系列过滤器...假设用户输入了一些过滤器,并将每个过滤器保存在一个集合中,例如:

ObservableCollection<IFilterBase<TItem>> Filters;

然后,完整的项目集合可以变成一个过滤的项目集合,例如:

source.Where(item => Filters.All(filter => filter.ApplyFilter(item)))

为了使MVVM准备好过滤的项目集合,我在一个项目中使用了以下帮助器类:

public class ObservableLinq<TIn, TOut> : IEnumerable<TOut>, INotifyCollectionChanged
{
    private ObservableCollection<TIn> _Source;
    private Func<IEnumerable<TIn>, IEnumerable<TOut>> _Transformation;

    public ObservableLinq(ObservableCollection<TIn> source, Func<IEnumerable<TIn>, IEnumerable<TOut>> transformation)
    {
        _Source = source;
        _Transformation = transformation;
        _Source.CollectionChanged += Source_CollectionChanged;
    }

    public ObservableLinq(IEnumerable<TIn> source, Func<IEnumerable<TIn>, IEnumerable<TOut>> transformation)
        : this(source as ObservableCollection<TIn> ?? new ObservableCollection<TIn>(source), transformation)
    {
    }

    private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        RaiseCollectionChanged();
    }

    public IEnumerator<TOut> GetEnumerator()
    {
        return _Transformation(_Source).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    // could be a property as well, but this empathizes, that the source collection is not the primary functionality here
    public ObservableCollection<TIn> GetSourceCollection()
    {
        return _Source;
    }


    public event NotifyCollectionChangedEventHandler CollectionChanged;

    protected void RaiseCollectionChanged()
    {
        var handler = CollectionChanged;
        if (handler != null)
        {
            // always reset as it would be pretty complicated to track the actual changes across all the linq thingies
            handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }

    /// <summary>
    /// Call when a filter relevant property changed on source collection entries
    /// </summary>
    public void CollectionChangedNeeded()
    {
        RaiseCollectionChanged();
    }
}

用法:

public ObservableLinq<TItem, TItem> FilteredItems { get {...} set {...} }

// init:
FilteredItems = new ObservableLinq<TItem, TItem>(ItemsList, source.Where(item => Filters.All(filter => filter.ApplyFilter(item))));

然后,当item集合更改,item属性更改,活动的filter集合更改或filter属性更改时,触发已过滤项目的更新(当source集合为ObservableCollection时,将注意项集合的更改)

FilteredItems.CollectionChangedNeeded();

与WPF提供的控件的内置筛选器功能相比,使用这种方法更灵活。 基于正则表达式的过滤器,用于自定义属性类型的过滤器,...在每种过滤器类型没有太多负担的情况下都可以实现。 只是过滤基础结构的初始设置并不是很简单。

暂无
暂无

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

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