} // ListViewUnloaded

        // ----------------------------------------------------------------------
        private void ThumbPreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (!(sender is Thumb thumb))
            {
                return;
            }
            var gridViewColumn = FindParentColumn(thumb);

            if (gridViewColumn == null)
            {
                return;
            }

            // suppress column resizing for proportional, fixed and range fill columns
            if (ProportionalColumn.IsProportionalColumn(gridViewColumn) || FixedColumn.IsFixedColumn(gridViewColumn) || IsFillColumn(gridViewColumn))
            {
                thumb.Cursor = null;
                return;
            }

            // check range column bounds
            if (thumb.IsMouseCaptured && RangeColumn.IsRangeColumn(gridViewColumn))
            {
                var minWidth = RangeColumn.GetRangeMinWidth(gridViewColumn);
                var maxWidth = RangeColumn.GetRangeMaxWidth(gridViewColumn);

                if (minWidth.HasValue && maxWidth.HasValue && minWidth > maxWidth)
                {
                    return;                                                                // invalid case
                }
                if (_resizeCursor == null)
                {
                    _resizeCursor = thumb.Cursor;                        // save the resize cursor
                }
                if (minWidth.HasValue && gridViewColumn.Width <= minWidth.Value)
                {
                    thumb.Cursor = Cursors.No;
                }
                else if (maxWidth.HasValue && gridViewColumn.Width >= maxWidth.Value)
                {
                    thumb.Cursor = Cursors.No;
                }
                else
                {
                    thumb.Cursor = _resizeCursor; // between valid min/max
                }
            }
        } // ThumbPreviewMouseMove
        } // ThumbPreviewMouseMove

        // ----------------------------------------------------------------------
        private void ThumbPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var thumb          = (Thumb)sender;
            var gridViewColumn = FindParentColumn(thumb);

            if (gridViewColumn == null)
            {
                throw new InvalidOperationException("Could not find parent column");
            }

            // suppress column resizing for proportional, fixed and range fill columns
            if (ProportionalColumn.IsProportionalColumn(gridViewColumn) || FixedColumn.IsFixedColumn(gridViewColumn) || IsFillColumn(gridViewColumn))
            {
                e.Handled = true;
            }
        } // ThumbPreviewMouseLeftButtonDown
        } // ThumbPreviewMouseLeftButtonDown

        // ----------------------------------------------------------------------
        private void GridColumnWidthChanged(object sender, EventArgs e)
        {
            if (!_loaded)
            {
                return;
            }

            var gridViewColumn = (GridViewColumn)sender;

            if (gridViewColumn == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            // suppress column resizing for proportional and fixed columns
            if (ProportionalColumn.IsProportionalColumn(gridViewColumn) || FixedColumn.IsFixedColumn(gridViewColumn))
            {
                return;
            }

            // ensure range column within the bounds
            if (RangeColumn.IsRangeColumn(gridViewColumn))
            {
                // special case: auto column width - maybe conflicts with min/max range
                if (gridViewColumn.Width.Equals(double.NaN))
                {
                    _autoSizedColumn = gridViewColumn;
                    return; // handled by the change header size event
                }

                // ensure column bounds
                if (Math.Abs(SetRangeColumnToBounds(gridViewColumn) - 0) > ZeroWidthRange)
                {
                    return;
                }
            }

            DoResizeColumns();
        } // GridColumnWidthChanged
        } // Refresh

        // ----------------------------------------------------------------------
        private void RegisterEvents(DependencyObject start)
        {
            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(start); i++)
            {
                var childVisual = (Visual)VisualTreeHelper.GetChild(start, i);
                if (childVisual is Thumb thumb)
                {
                    var gridViewColumn = FindParentColumn(childVisual);
                    if (gridViewColumn != null)
                    {
                        if (ProportionalColumn.IsProportionalColumn(gridViewColumn) || FixedColumn.IsFixedColumn(gridViewColumn) ||
                            IsFillColumn(gridViewColumn))
                        {
                            thumb.IsHitTestVisible = false;
                        }
                        else
                        {
                            thumb.PreviewMouseMove           += ThumbPreviewMouseMove;
                            thumb.PreviewMouseLeftButtonDown += ThumbPreviewMouseLeftButtonDown;
                            DependencyPropertyDescriptor.FromProperty(GridViewColumn.WidthProperty, typeof(GridViewColumn))
                            .AddValueChanged(gridViewColumn, GridColumnWidthChanged);
                        }
                    }
                }
                else if (childVisual is GridViewColumnHeader columnHeader)
                {
                    columnHeader.SizeChanged += GridColumnHeaderSizeChanged;
                }
                else if (_scrollViewer == null && childVisual is ScrollViewer)
                {
                    _scrollViewer = (ScrollViewer)childVisual;
                    _scrollViewer.ScrollChanged += ScrollViewerScrollChanged;
                    // assume we do the regulation of the horizontal scrollbar
                    _scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                    _scrollViewer.VerticalScrollBarVisibility   = VerticalScrollBarVisibility;
                }

                RegisterEvents(childVisual); // recursive
            }
        } // RegisterEvents
        } // RegisterEvents

        // ----------------------------------------------------------------------
        private void UnregisterEvents(DependencyObject start)
        {
            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(start); i++)
            {
                var childVisual = (Visual)VisualTreeHelper.GetChild(start, i);
                if (childVisual is Thumb)
                {
                    var gridViewColumn = FindParentColumn(childVisual);
                    if (gridViewColumn != null)
                    {
                        var thumb = (Thumb)childVisual;
                        if (ProportionalColumn.IsProportionalColumn(gridViewColumn) || FixedColumn.IsFixedColumn(gridViewColumn) ||
                            IsFillColumn(gridViewColumn))
                        {
                            thumb.IsHitTestVisible = true;
                        }
                        else
                        {
                            thumb.PreviewMouseMove           -= ThumbPreviewMouseMove;
                            thumb.PreviewMouseLeftButtonDown -= ThumbPreviewMouseLeftButtonDown;
                            DependencyPropertyDescriptor.FromProperty(GridViewColumn.WidthProperty, typeof(GridViewColumn))
                            .RemoveValueChanged(gridViewColumn, GridColumnWidthChanged);
                        }
                    }
                }
                else if (childVisual is GridViewColumnHeader columnHeader)
                {
                    columnHeader.SizeChanged -= GridColumnHeaderSizeChanged;
                }
                else if (_scrollViewer == null && childVisual is ScrollViewer viewer)
                {
                    _scrollViewer = viewer;
                    _scrollViewer.ScrollChanged -= ScrollViewerScrollChanged;
                }

                UnregisterEvents(childVisual); // recursive
            }
        } // UnregisterEvents