Răsfoiți Sursa

Merge remote-tracking branch 'origin/feature/FormattedTextPort' into feature/FormattedTextPort

Benedikt Stebner 3 ani în urmă
părinte
comite
0f5c3a0322

+ 8 - 1
src/Avalonia.Controls.DataGrid/DataGrid.cs

@@ -2215,7 +2215,14 @@ namespace Avalonia.Controls
         /// <param name="e">PointerWheelEventArgs</param>
         protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
         {
-            e.Handled = e.Handled || UpdateScroll(e.Delta * DATAGRID_mouseWheelDelta);
+            if(UpdateScroll(e.Delta * DATAGRID_mouseWheelDelta))
+            {
+                e.Handled = true;
+            }
+            else
+            {
+                e.Handled = e.Handled || !ScrollViewer.GetIsScrollChainingEnabled(this);
+            }
         }
 
         internal bool UpdateScroll(Vector delta)

+ 30 - 4
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@@ -60,6 +60,12 @@ namespace Avalonia.Controls.Presenters
                 o => o.Viewport,
                 (o, v) => o.Viewport = v);
 
+        /// <summary>
+        /// Defines the <see cref="IsScrollChainingEnabled"/> property.
+        /// </summary>
+        public static readonly StyledProperty<bool> IsScrollChainingEnabledProperty =
+            ScrollViewer.IsScrollChainingEnabledProperty.AddOwner<ScrollContentPresenter>();
+
         private bool _canHorizontallyScroll;
         private bool _canVerticallyScroll;
         private bool _arranging;
@@ -138,6 +144,20 @@ namespace Avalonia.Controls.Presenters
             private set { SetAndRaise(ViewportProperty, ref _viewport, value); }
         }
 
+        /// <summary>
+        ///  Gets or sets if scroll chaining is enabled. The default value is true.
+        /// </summary>
+        /// <remarks>
+        ///  After a user hits a scroll limit on an element that has been nested within another scrollable element,
+        /// you can specify whether that parent element should continue the scrolling operation begun in its child element.
+        /// This is called scroll chaining.
+        /// </remarks>
+        public bool IsScrollChainingEnabled
+        {
+            get => GetValue(IsScrollChainingEnabledProperty);
+            set => SetValue(IsScrollChainingEnabledProperty, value);
+        }
+
         /// <inheritdoc/>
         IControl? IScrollAnchorProvider.CurrentAnchor
         {
@@ -405,8 +425,11 @@ namespace Avalonia.Controls.Presenters
                     _activeLogicalGestureScrolls[e.Id] = delta;
                 }
 
-                Offset = new Vector(x, y);
-                e.Handled = true;
+                Vector newOffset = new Vector(x, y);
+                bool offsetChanged = newOffset != Offset;
+                Offset = newOffset;
+
+                e.Handled = !IsScrollChainingEnabled || offsetChanged;
             }
         }
 
@@ -440,8 +463,11 @@ namespace Avalonia.Controls.Presenters
                     x = Math.Min(x, Extent.Width - Viewport.Width);
                 }
 
-                Offset = new Vector(x, y);
-                e.Handled = true;
+                Vector newOffset = new Vector(x, y);
+                bool offsetChanged = newOffset != Offset;
+                Offset = newOffset;
+
+                e.Handled = !IsScrollChainingEnabled || offsetChanged;
             }
         }
 

+ 52 - 0
src/Avalonia.Controls/ScrollViewer.cs

@@ -181,6 +181,14 @@ namespace Avalonia.Controls
                 nameof(AllowAutoHide),
                 true);
 
+        /// <summary>
+        /// Defines the <see cref="IsScrollChainingEnabled"/> property.
+        /// </summary>
+        public static readonly AttachedProperty<bool> IsScrollChainingEnabledProperty =
+            AvaloniaProperty.RegisterAttached<ScrollViewer, Control, bool>(
+                nameof(IsScrollChainingEnabled),
+                defaultValue: true);
+
         /// <summary>
         /// Defines the <see cref="ScrollChanged"/> event.
         /// </summary>
@@ -418,6 +426,20 @@ namespace Avalonia.Controls
             set => SetValue(AllowAutoHideProperty, value);
         }
 
+        /// <summary>
+        ///  Gets or sets if scroll chaining is enabled. The default value is true.
+        /// </summary>
+        /// <remarks>
+        ///  After a user hits a scroll limit on an element that has been nested within another scrollable element,
+        /// you can specify whether that parent element should continue the scrolling operation begun in its child element.
+        /// This is called scroll chaining.
+        /// </remarks>
+        public bool IsScrollChainingEnabled
+        {
+            get => GetValue(IsScrollChainingEnabledProperty);
+            set => SetValue(IsScrollChainingEnabledProperty, value);
+        }
+
         /// <summary>
         /// Scrolls the content up one line.
         /// </summary>
@@ -548,6 +570,36 @@ namespace Avalonia.Controls
             return control.GetValue(AllowAutoHideProperty);
         }
 
+        /// <summary>
+        /// Sets the value of the IsScrollChainingEnabled attached property.
+        /// </summary>
+        /// <param name="control">The control to set the value on.</param>
+        /// <param name="value">The value of the property.</param>
+        /// <remarks>
+        ///  After a user hits a scroll limit on an element that has been nested within another scrollable element,
+        /// you can specify whether that parent element should continue the scrolling operation begun in its child element.
+        /// This is called scroll chaining.
+        /// </remarks>
+        public static void SetIsScrollChainingEnabled(Control control, bool value)
+        {
+            control.SetValue(IsScrollChainingEnabledProperty, value);
+        }
+
+        /// <summary>
+        ///  Gets the value of the IsScrollChainingEnabled attached property.
+        /// </summary>
+        /// <param name="control">The control to read the value from.</param>
+        /// <returns>The value of the property.</returns>
+        /// <remarks>
+        ///  After a user hits a scroll limit on an element that has been nested within another scrollable element,
+        /// you can specify whether that parent element should continue the scrolling operation begun in its child element.
+        /// This is called scroll chaining.
+        /// </remarks>
+        public static bool GetIsScrollChainingEnabled(Control control)
+        {
+            return control.GetValue(IsScrollChainingEnabledProperty);
+        }
+
         /// <summary>
         /// Gets the value of the VerticalScrollBarVisibility attached property.
         /// </summary>

+ 2 - 0
src/Avalonia.Themes.Default/Controls/ListBox.xaml

@@ -6,6 +6,7 @@
   <Setter Property="Padding" Value="4"/>
   <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
   <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
+  <Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
   <Setter Property="Template">
     <ControlTemplate>
       <Border Name="border" BorderBrush="{TemplateBinding BorderBrush}"
@@ -15,6 +16,7 @@
                       Background="{TemplateBinding Background}"
                       HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
                       VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
+                      IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
                       AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
           <ItemsPresenter Name="PART_ItemsPresenter"
                           Items="{TemplateBinding Items}"

+ 2 - 1
src/Avalonia.Themes.Default/Controls/ScrollViewer.xaml

@@ -15,7 +15,8 @@
                                   Extent="{TemplateBinding Extent, Mode=TwoWay}"
                                   Margin="{TemplateBinding Padding}"
                                   Offset="{TemplateBinding Offset, Mode=TwoWay}"
-                                  Viewport="{TemplateBinding Viewport, Mode=TwoWay}">
+                                  Viewport="{TemplateBinding Viewport, Mode=TwoWay}"
+                                  IsScrollChainingEnabled="{TemplateBinding IsScrollChainingEnabled}">
             <ScrollContentPresenter.GestureRecognizers>
               <ScrollGestureRecognizer
                 CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}"

+ 2 - 0
src/Avalonia.Themes.Default/Controls/TextBox.xaml

@@ -25,6 +25,7 @@
     <Setter Property="SelectionForegroundBrush" Value="{DynamicResource HighlightForegroundBrush}"/>
     <Setter Property="Padding" Value="4"/>
     <Setter Property="ContextFlyout" Value="{StaticResource DefaultTextBoxContextFlyout}" />
+    <Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
     <Setter Property="Template">
       <ControlTemplate>
         <Border Name="border"
@@ -59,6 +60,7 @@
                 <ScrollViewer Grid.Column="1" Grid.ColumnSpan="1"
                               HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
                               VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
+                              IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
                               AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
                   <Panel>
                     <TextBlock Name="watermark"

+ 2 - 0
src/Avalonia.Themes.Default/Controls/TreeView.xaml

@@ -5,6 +5,7 @@
   <Setter Property="Padding" Value="4"/>
   <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
   <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
+  <Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
   <Setter Property="Template">
     <ControlTemplate>
       <Border BorderBrush="{TemplateBinding BorderBrush}"
@@ -13,6 +14,7 @@
         <ScrollViewer Background="{TemplateBinding Background}"
                       HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
                       VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
+                      IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
                       AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
           <ItemsPresenter Name="PART_ItemsPresenter"
                           Items="{TemplateBinding Items}"

+ 2 - 0
src/Avalonia.Themes.Fluent/Controls/ListBox.xaml

@@ -16,6 +16,7 @@
     <Setter Property="BorderThickness" Value="{DynamicResource ListBoxBorderThemeThickness}" />
     <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
     <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />        
+    <Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />        
     <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />    
     <Setter Property="Template">
       <ControlTemplate>
@@ -28,6 +29,7 @@
           <ScrollViewer Name="PART_ScrollViewer"
                         HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
                         VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
+                        IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
                         AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
             <ItemsPresenter Name="PART_ItemsPresenter"
                             Items="{TemplateBinding Items}"

+ 2 - 1
src/Avalonia.Themes.Fluent/Controls/ScrollViewer.xaml

@@ -34,7 +34,8 @@
                                   Extent="{TemplateBinding Extent, Mode=TwoWay}"
                                   Margin="{TemplateBinding Padding}"
                                   Offset="{TemplateBinding Offset, Mode=TwoWay}"
-                                  Viewport="{TemplateBinding Viewport, Mode=TwoWay}">
+                                  Viewport="{TemplateBinding Viewport, Mode=TwoWay}"
+                                  IsScrollChainingEnabled="{TemplateBinding IsScrollChainingEnabled}">
             <ScrollContentPresenter.GestureRecognizers>
               <ScrollGestureRecognizer
                 CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}"

+ 2 - 0
src/Avalonia.Themes.Fluent/Controls/TextBox.xaml

@@ -41,6 +41,7 @@
     <Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" />
     <Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" />
     <Setter Property="FocusAdorner" Value="{x:Null}" />
+    <Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
     <Setter Property="ContextFlyout" Value="{StaticResource DefaultTextBoxContextFlyout}" />
     <Setter Property="Template">
       <ControlTemplate>
@@ -68,6 +69,7 @@
                              DockPanel.Dock="Top" />
                   <ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
                                 VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
+                                IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
                                 AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
                       <Panel>
                         <TextBlock Name="PART_Watermark"

+ 2 - 0
src/Avalonia.Themes.Fluent/Controls/TreeView.xaml

@@ -6,6 +6,7 @@
   <Setter Property="Padding" Value="0" />
   <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
   <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
+  <Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
   <Setter Property="Template">
     <ControlTemplate>
       <Border BorderBrush="{TemplateBinding BorderBrush}"
@@ -14,6 +15,7 @@
         <ScrollViewer Background="{TemplateBinding Background}"
                       HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
                       VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
+                      IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
                       AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
           <ItemsPresenter Name="PART_ItemsPresenter"
                           Items="{TemplateBinding Items}"