MahApps/MahApps.Metro · error · ArgumentException

This dependency property can only be attached to a ScrollVie

Error message

This dependency property can only be attached to a ScrollViewer

What it means

Thrown by OnBubbleUpScrollEventToParentScrollviewerPropertyChanged when the sender is not a ScrollViewer. The BubbleUpScrollEventToParentScrollviewer attached property only hooks PreviewMouseWheel on a ScrollViewer; attaching it to any other element type is rejected. Although the property is marked AttachedPropertyBrowsableForType(ScrollViewer), a change callback still validates the runtime type defensively.

Source

Thrown at src/MahApps.Metro/Controls/Helper/ScrollViewerHelper.cs:437

        {
            return (bool)obj.GetValue(BubbleUpScrollEventToParentScrollviewerProperty);
        }

        /// <summary>Helper for setting <see cref="BubbleUpScrollEventToParentScrollviewerProperty"/> on <paramref name="obj"/>.</summary>
        /// <param name="obj"><see cref="DependencyObject"/> to set <see cref="BubbleUpScrollEventToParentScrollviewerProperty"/> on.</param>
        /// <param name="value">BubbleUpScrollEventToParentScrollviewerProperty property value.</param>
        [Category(AppName.MahApps)]
        [AttachedPropertyBrowsableForType(typeof(ScrollViewer))]
        public static void SetBubbleUpScrollEventToParentScrollviewer(DependencyObject obj, bool value)
        {
            obj.SetValue(BubbleUpScrollEventToParentScrollviewerProperty, BooleanBoxes.Box(value));
        }

        public static void OnBubbleUpScrollEventToParentScrollviewerPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (!(sender is ScrollViewer viewer))
            {
                throw new ArgumentException("This dependency property can only be attached to a ScrollViewer", nameof(sender));
            }

            if (e.OldValue != e.NewValue)
            {
                if ((bool)e.NewValue == true)
                {
                    viewer.PreviewMouseWheel += HandlePreviewMouseWheel;
                }
                else if ((bool)e.NewValue == false)
                {
                    viewer.PreviewMouseWheel -= HandlePreviewMouseWheel;
                }
            }
        }

        private static readonly List<MouseWheelEventArgs> ReentrantList = new();

        private static void HandlePreviewMouseWheel(object? sender, MouseWheelEventArgs e)

View on GitHub (pinned to 72099e310b)

Solutions

  1. Set BubbleUpScrollEventToParentScrollviewer on a ScrollViewer element only.
  2. If the scroll host is inside another control (e.g. ListBox), find/replace its internal ScrollViewer or use the appropriate ScrollViewer directly.
  3. Remove the attached property from incompatible elements.
  4. In code-behind, type-check the target before SetValue.

Example fix

<!-- before -->
<Grid helper:ScrollViewerHelper.BubbleUpScrollEventToParentScrollviewer="True" /> <!-- throws -->

<!-- after -->
<ScrollViewer helper:ScrollViewerHelper.BubbleUpScrollEventToParentScrollviewer="True"> ... </ScrollViewer>
Defensive patterns

Strategy: type-guard

Validate before calling

if (obj is not ScrollViewer)
{
    throw new ArgumentException(
        "BubbleUpScrollEventToParentScrollviewer requires a ScrollViewer.",
        nameof(obj));
}

Type guard

static bool IsScrollViewer(DependencyObject d) => d is ScrollViewer;

Prevention

When it happens

Trigger: Setting helper:ScrollViewerHelper.BubbleUpScrollEventToParentScrollviewer on a non-ScrollViewer element (Grid, Border, StackPanel, ListBox); applying the attached property via code-behind SetValue on an arbitrary DependencyObject.

Common situations: Trying to forward scroll events from a non-ScrollViewer container; copy-pasting the attached property onto the wrong element in XAML.

Related errors


AI-assisted analysis of MahApps/MahApps.Metro@72099e310b (2026-08-13). Data as JSON: /api/errors/ae731eaa0c048a61. Report an issue: GitHub.