예제 #1
0
        /// <summary>
        /// Callback executed when an item's property gets updated
        /// </summary>
        /// <param name="sender">
        /// Items
        /// </param>
        /// <param name="e">
        /// Argument containing the name of the property that raised the changes
        /// </param>
        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // lots of properties gets updated, we watch only those which belongs to visible fieldnames
            // and those who were registered for propertychanges monitoring
            // and of course if the item is still on the list
            if (_valueGetters.Any(vg => vg.FieldName == e.PropertyName))
            {
                PropertyFilterValueGetter pf =
                    _valueGetters.FirstOrDefault(vg => vg.FieldName == e.PropertyName);
                if (pf.MonitorPropertyChanged && _substituteSource.Contains(sender))
                {
                    // To avoid doing a refresh on a property change which would end in a very hawful user experience
                    // we simulate a replace to the collection because the filter is automatically applied in this case
                    int index = _substituteSource.IndexOf(sender);

                    var argsReplace = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,
                                                                           new List <object> {
                        sender
                    },
                                                                           new List <object> {
                        sender
                    }, index);
                    _substituteSource.RaiseCollectionChanged(argsReplace);
                }

                NotifyResults(); // Notify results
            }
        }
        /// <summary>
        /// Method called when FilterColumns property changes
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Raised when a a property filter refers to a non existing candidate object type property
        /// </exception>
        private void SetFilterColumns()
        {
            var propertyFilters = Items.Cast<ValueFilter>().ToList();

            if (UnderlyingType.Equals(typeof (string)) || UnderlyingType.IsValueType)
            {
                // for native types, only one ValueFilter accepted to apply string format or IValueConverter 
                if (propertyFilters.Count > 1)
                {
                    throw new InvalidOperationException(
                        "Only one property filter is authorized when underlying type is String or a value type.");
                }


// Then if there is no property filter at all, there is no conversion needed and we build a defautl property getter
                // and there is one, we build a property getter accordingly
                _valueGetters.Add(propertyFilters.Count == 0
                                      ? new PropertyFilterValueGetter(new ValueFilter())
                                      : new PropertyFilterValueGetter(propertyFilters[0]));
            }
                

// if the underlying type if neither a string nor value type, then it is a reference type
            else
            {
                IEnumerable<PropertyFilter> apfs;


// if there is no PropertyFilter defined, we build it by default based on every instance public properties of the underlying type
                if (propertyFilters.Count == 0)
                {
                    apfs = new List<PropertyFilter>();


// Get the type Properties
                    var pis = UnderlyingType.GetProperties(BindingFlags.Public | BindingFlags.Instance);


// iterate
                    foreach (var propertyInfo in pis)
                    {
                        var pf = new PropertyFilter(propertyInfo.Name, DefaultMonitorPropertyChanges);
                        var pfvg = new PropertyFilterValueGetter(pf, UnderlyingType); // Generate...
                        _valueGetters.Add(pfvg); // ...and add value getter for each properties
                    }
                }
                else
                {
                    // and thus every ValueFilter must be PropertyFilter
                    if (propertyFilters.Any(p => !(p is PropertyFilter)))
                    {
                        throw new InvalidOperationException("ValueFilter can't be used with reference type.");
                    }

                    apfs = propertyFilters.Cast<PropertyFilter>().ToList();
                    foreach (PropertyFilter pf in apfs)
                    {
                        // Get the PropertyInfo
                        PropertyInfo pi = UnderlyingType.GetProperty(pf.FieldName);

                        // this info is mandatory
                        if (pi == null)
                        {
                            throw new InvalidOperationException(
                                string.Format("Cant't find the property {0} for type {1}", 
                                              pf.FieldName, UnderlyingType.Name));
                        }

                        // If pi is ok, build the value getter and add it to the list
                        var pfvg = new PropertyFilterValueGetter(pf, UnderlyingType);
                        _valueGetters.Add(pfvg);
                    }
                }

                // If there is no ValueFilter which is set to be monitored for property changes, we keep track of it to avoid to subscribe to propertychanged event later on
                _hasAnyPropertyChangesToMonitor = apfs.Any(p => p.MonitorPropertyChanged);
            }
        }
예제 #3
0
        /// <summary>
        /// Method called when FilterColumns property changes
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Raised when a a property filter refers to a non existing candidate object type property
        /// </exception>
        private void SetFilterColumns()
        {
            var propertyFilters = Items.Cast <ValueFilter>().ToList();

            if (UnderlyingType.Equals(typeof(string)) || UnderlyingType.IsValueType)
            {
                // for native types, only one ValueFilter accepted to apply string format or IValueConverter
                if (propertyFilters.Count > 1)
                {
                    throw new InvalidOperationException(
                              "Only one property filter is authorized when underlying type is String or a value type.");
                }


// Then if there is no property filter at all, there is no conversion needed and we build a defautl property getter
                // and there is one, we build a property getter accordingly
                _valueGetters.Add(propertyFilters.Count == 0
                                      ? new PropertyFilterValueGetter(new ValueFilter())
                                      : new PropertyFilterValueGetter(propertyFilters[0]));
            }


// if the underlying type if neither a string nor value type, then it is a reference type
            else
            {
                IEnumerable <PropertyFilter> apfs;


// if there is no PropertyFilter defined, we build it by default based on every instance public properties of the underlying type
                if (propertyFilters.Count == 0)
                {
                    apfs = new List <PropertyFilter>();


// Get the type Properties
                    var pis = UnderlyingType.GetProperties(BindingFlags.Public | BindingFlags.Instance);


// iterate
                    foreach (var propertyInfo in pis)
                    {
                        var pf   = new PropertyFilter(propertyInfo.Name, DefaultMonitorPropertyChanges);
                        var pfvg = new PropertyFilterValueGetter(pf, UnderlyingType); // Generate...
                        _valueGetters.Add(pfvg);                                      // ...and add value getter for each properties
                    }
                }
                else
                {
                    // and thus every ValueFilter must be PropertyFilter
                    if (propertyFilters.Any(p => !(p is PropertyFilter)))
                    {
                        throw new InvalidOperationException("ValueFilter can't be used with reference type.");
                    }

                    apfs = propertyFilters.Cast <PropertyFilter>().ToList();
                    foreach (PropertyFilter pf in apfs)
                    {
                        // Get the PropertyInfo
                        PropertyInfo pi = UnderlyingType.GetProperty(pf.FieldName);

                        // this info is mandatory
                        if (pi == null)
                        {
                            throw new InvalidOperationException(
                                      string.Format("Cant't find the property {0} for type {1}",
                                                    pf.FieldName, UnderlyingType.Name));
                        }

                        // If pi is ok, build the value getter and add it to the list
                        var pfvg = new PropertyFilterValueGetter(pf, UnderlyingType);
                        _valueGetters.Add(pfvg);
                    }
                }

                // If there is no ValueFilter which is set to be monitored for property changes, we keep track of it to avoid to subscribe to propertychanged event later on
                _hasAnyPropertyChangesToMonitor = apfs.Any(p => p.MonitorPropertyChanged);
            }
        }