/// <summary>
        /// Notifies all registered property change listeners about a property change.
        /// </summary>
        /// <param name="property">The changed proeprty.</param>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="property"/> has an invalid value.</exception>
        /// <seealso cref="AddPropertyChangeListener"/>
        /// <seealso cref="RemovePropertyChangeListener"/>
        /// <seealso cref="IColumnOrRowPropertyChangeListener"/>
        internal void OnPropertyChanged(ColumnOrRowProperty property)
        {
            switch (property)
            {
            case ColumnOrRowProperty.Name:
            case ColumnOrRowProperty.Size:
            case ColumnOrRowProperty.MinSize:
            case ColumnOrRowProperty.MaxSize:
            case ColumnOrRowProperty.SharedSizeGroup:
            case ColumnOrRowProperty.StartAt:
            case ColumnOrRowProperty.ExtendTo:
                break;

            default:
                throw new InvalidEnumArgumentException("property", (int)property, typeof(ColumnOrRowProperty));
            }

            for (int i = propertyChangeListeners.Count - 1; i >= 0; i--)
            {
                var l = propertyChangeListeners[i].Target as IColumnOrRowPropertyChangeListener;
                if (l == null)
                {
                    propertyChangeListeners.RemoveAt(i);
                }
                else
                {
                    l.PropertyChanged(this, property);
                }
            }

            OnPropertyChanged(property.ToString());
        }
            /// <summary>
            /// Processes a change notification.
            /// </summary>
            /// <param name="columnOrRow">The <see cref="ColumnOrRowBase"/> instance whose property value was changed.
            ///   This must not be <see langword="null"/>.</param>
            /// <param name="property">The modified property.</param>
            public void PropertyChanged(ColumnOrRowBase columnOrRow, ColumnOrRowProperty property)
            {
                switch (property)
                {
                case ColumnOrRowProperty.Name:
                    owner.InvalidateMaps();
                    goto case ColumnOrRowProperty.ExtendTo;

                case ColumnOrRowProperty.StartAt:
                case ColumnOrRowProperty.ExtendTo:
                    owner.UpdatePlacement();
                    break;

                case ColumnOrRowProperty.Size:
                    ForEachColumnOrRow((idx, cr) => {
                        if (cr == columnOrRow)
                        {
                            owner.controller.SetSize(idx, cr.Size);
                        }
                    });
                    break;

                case ColumnOrRowProperty.MinSize:
                    ForEachColumnOrRow((idx, cr) => {
                        if (cr == columnOrRow)
                        {
                            owner.controller.SetMinSize(idx, cr.MinSize);
                        }
                    });
                    break;

                case ColumnOrRowProperty.MaxSize:
                    ForEachColumnOrRow((idx, cr) => {
                        if (cr == columnOrRow)
                        {
                            owner.controller.SetMaxSize(idx, cr.MaxSize);
                        }
                    });
                    break;

                case ColumnOrRowProperty.SharedSizeGroup:
                    ForEachColumnOrRow((idx, cr) => {
                        if (cr == columnOrRow)
                        {
                            owner.controller.SetSharedSizeGroup(idx, cr.SharedSizeGroup);
                        }
                    });
                    break;
                }
            }