My filterable solution

My filterable solution

Old forum URL: forums.lhotka.net/forums/t/2605.aspx


Piccolo posted on Thursday, March 29, 2007

Hi all,

    I´m using CSLA 2.0 and I need that my collections can be filtered. I developed a solution and I´d like community to comment my solution. My filter is an abstract generics class in order to obtain strongly typed filters. The compare method must be override. compare method is strongly typed so you don´t need to use reflection and you can combine conditions into this method.

Example:

        private Filtro _filtro = new Filtro("Filtro", true);

        public class Filtro : CSLA.Core.Filter<ConflictoEscolar>
        {
            #region variables

            // Filter constrains
            private int _idNivelGravedad = -1;         
            private int _idNivelPrioridad = -1;
            private int _idEstadoResolucion = -1;

            #endregion

            #region Propiedades

            public int IdNivelGravedad
            {
                get { return _idNivelGravedad; }
                set
                {
                    if (_idNivelGravedad != value)
                    {
                        _idNivelGravedad = value;
                        _parentFilter.ApplyFilters();
                    }
                }
            }

            public int IdNivelPrioridad
            {
                get { return _idNivelPrioridad; }
                set
                {
                    if (_idNivelPrioridad!= value)
                    {
                        _idNivelPrioridad = value;
                        _parentFilter.ApplyFilters();
                    }
                }
            }

            public int IdEstadoResolucion
            {
                get { return _idEstadoResolucion; }
                set
                {
                    if (_idEstadoResolucion != value)
                    {
                        _idEstadoResolucion= value;
                        _parentFilter.ApplyFilters();
                    }
                }
            }

            #endregion

            #region Constructores

            public Filtro(string name)
                : base(name)
            { }

            public Filtro(string name, bool activate)
                : base(name)
            {
                _isActive = activate;
            }

            #endregion

            #region sobrecarga

            public override bool Compare(ConflictoEscolar obj)
            {
                // I can use object properties to compose the filter because obj is strongly typed
                bool result = ((_idNivelGravedad == -1) || (_idNivelGravedad == obj.IdNivelGravedad));
                result = result && ((_idNivelPrioridad == -1) || (_idNivelPrioridad == obj.IdNivelPrioridad));
                result = result && ((_idEstadoResolucion == -1) || (_idEstadoResolucion == obj.IdEstadoResolucion));
                return result;
            }

            #endregion


Filterable Code:

    public class FilterableSimpleCollectionBase : SortableSimpleCollectionBase
    {
        #region Variables

        private ArrayList _unfilteredList;
        private bool _isFiltered = false;
        private bool _autofilter = true;
        private List<IFilter> _filterList = new List<IFilter> ();

        #endregion

        #region Propiedades

        protected bool IsFiltered
        {
            get { return _isFiltered; }
        }

        protected bool AutoFilter
        {
            get { return _autofilter; }
            set
            {
                if (_autofilter != value)
                {
                    _autofilter = value;
                    ApplyFilters();
                }
            }
        }

        #endregion

        public void ApplyFilters()
        {
            if ((!_isFiltered) && (_filterList.Count > 0))
            {
                _unfilteredList = new ArrayList(InnerList);
            }

            if (_filterList.Count > 0)
            {
                InnerList.Clear();
                foreach (object item in _unfilteredList)
                {
                    foreach (IFilter filter in _filterList)
                    {
                        if ((filter.IsActive) && (filter.Compare(item)))
                        {
                            InnerList.Add(item);
                        }
                    }
                }
                _isFiltered = true;
            }
        }

        public void AddFilter(IFilter filter)
        {
            if (FindFilter(filter.Name) == null)
            {
                filter.ParentFilter = this;
                _filterList.Add(filter);
                if (_autofilter)
                {
                    ApplyFilters();
                }
            }
        }

        public void RemoveFilter(string name)
        {
            if (_isFiltered)
            {
                IFilter filter = FindFilter(name);
                if ((filter != null) && (filter.IsActive))
                {
                    InnerList.Clear();
                    ApplyFilters();
                }
                if (filter != null)
                {
                    _filterList.Remove(filter);
                }
            }
        }

        public IFilter FindFilter(string name)
        {
            foreach (IFilter filter in _filterList)
            {
                if (filter.Name == name)
                    return filter;
            }
            return null;
        }

    }

    public abstract class Filter<T> : IFilter
    {
        protected bool _isActive = false;
        protected string _name = string.Empty;
        protected FilterableSimpleCollectionBase _parentFilter = null;

        #region Miembros de IFilter

        public string Name
        {
            get { return _name; }
        }

        public bool IsActive
        {
            get {return _isActive;}
            set
            {
                if (_isActive != value)
                {
                    _isActive = value;
                    if(_parentFilter != null)
                        _parentFilter.ApplyFilters();
                }
            }
        }

        public object ParentFilter
        {
            get { return _parentFilter; }
            set
            {
                if(value is FilterableSimpleCollectionBase)
                _parentFilter = (FilterableSimpleCollectionBase) value;
            }
        }
       
        public bool Compare(object obj)
        {
            try
            {
                T object1 = (T)obj;
                return Compare(object1);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        public Filter(string name)
        {
            _name = name;
        }

        public abstract bool Compare(T obj);

    }

    public interface IFilter
    {
        string Name
        {
            get;
        }

        bool IsActive
        {
            get;
            set;
        }

        object ParentFilter
        {
            get;
            set;
        }

        bool Compare(object obj);
    }


Copyright (c) Marimer LLC