Browse Source

make AreVerticalSnapPointsRegular and AreHorizontalSnapPointsRegular styled properties

pull/9961/head
Emmanuel Hansen 3 years ago
parent
commit
feddc7e1c4
  1. 35
      src/Avalonia.Controls/ItemsControl.cs
  2. 49
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  3. 8
      src/Avalonia.Controls/Primitives/IScrollSnapPointsInfo.cs
  4. 32
      src/Avalonia.Controls/VirtualizingStackPanel.cs
  5. 2
      src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml
  6. 3
      src/Avalonia.Themes.Fluent/Controls/ListBox.xaml
  7. 2
      src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml
  8. 6
      src/Avalonia.Themes.Simple/Controls/ListBox.xaml

35
src/Avalonia.Controls/ItemsControl.cs

@ -74,6 +74,18 @@ namespace Avalonia.Controls
/// </summary>
public static readonly StyledProperty<IBinding?> DisplayMemberBindingProperty =
AvaloniaProperty.Register<ItemsControl, IBinding?>(nameof(DisplayMemberBinding));
/// <summary>
/// Defines the <see cref="AreHorizontalSnapPointsRegular"/> property.
/// </summary>
public static readonly StyledProperty<bool> AreHorizontalSnapPointsRegularProperty =
AvaloniaProperty.Register<ItemsControl, bool>(nameof(AreHorizontalSnapPointsRegular));
/// <summary>
/// Defines the <see cref="AreVerticalSnapPointsRegular"/> property.
/// </summary>
public static readonly StyledProperty<bool> AreVerticalSnapPointsRegularProperty =
AvaloniaProperty.Register<ItemsControl, bool>(nameof(AreVerticalSnapPointsRegular));
/// <summary>
/// Gets or sets the <see cref="IBinding"/> to use for binding to the display member of each item.
@ -94,6 +106,7 @@ namespace Avalonia.Controls
private Tuple<int, Control>? _containerBeingPrepared;
private ScrollViewer? _scrollViewer;
private ItemsPresenter? _itemsPresenter;
private IScrollSnapPointsInfo? _scrolSnapPointInfo;
/// <summary>
/// Initializes a new instance of the <see cref="ItemsControl"/> class.
@ -245,6 +258,24 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// Gets or sets whether the horizontal snap points for the <see cref="ItemsControl"/> are equidistant from each other.
/// </summary>
public bool AreHorizontalSnapPointsRegular
{
get { return GetValue(AreHorizontalSnapPointsRegularProperty); }
set { SetValue(AreHorizontalSnapPointsRegularProperty, value); }
}
/// <summary>
/// Gets or sets whether the vertical snap points for the <see cref="ItemsControl"/> are equidistant from each other.
/// </summary>
public bool AreVerticalSnapPointsRegular
{
get { return GetValue(AreVerticalSnapPointsRegularProperty); }
set { SetValue(AreVerticalSnapPointsRegularProperty, value); }
}
/// <summary>
/// Returns the container for the item at the specified index.
/// </summary>
@ -296,8 +327,6 @@ namespace Avalonia.Controls
/// Gets the currently realized containers.
/// </summary>
public IEnumerable<Control> GetRealizedContainers() => Presenter?.GetRealizedContainers() ?? Array.Empty<Control>();
public bool AreHorizontalSnapPointsRegular => _itemsPresenter?.AreHorizontalSnapPointsRegular ?? false;
public bool AreVerticalSnapPointsRegular => _itemsPresenter?.AreVerticalSnapPointsRegular ?? false;
/// <summary>
/// Creates or a container that can be used to display an item.
@ -399,6 +428,8 @@ namespace Avalonia.Controls
base.OnApplyTemplate(e);
_scrollViewer = e.NameScope.Find<ScrollViewer>("PART_ScrollViewer");
_itemsPresenter = e.NameScope.Find<ItemsPresenter>("PART_ItemsPresenter");
_scrolSnapPointInfo = _itemsPresenter as IScrollSnapPointsInfo;
}
/// <summary>

49
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@ -21,8 +21,21 @@ namespace Avalonia.Controls.Presenters
private PanelContainerGenerator? _generator;
private ILogicalScrollable? _logicalScrollable;
private IScrollSnapPointsInfo? _scrollSnapPointsInfo;
private EventHandler? _scrollInvalidated;
/// <summary>
/// Defines the <see cref="AreHorizontalSnapPointsRegular"/> property.
/// </summary>
public static readonly StyledProperty<bool> AreHorizontalSnapPointsRegularProperty =
AvaloniaProperty.Register<ItemsControl, bool>(nameof(AreHorizontalSnapPointsRegular));
/// <summary>
/// Defines the <see cref="AreVerticalSnapPointsRegular"/> property.
/// </summary>
public static readonly StyledProperty<bool> AreVerticalSnapPointsRegularProperty =
AvaloniaProperty.Register<ItemsControl, bool>(nameof(AreVerticalSnapPointsRegular));
/// <summary>
/// Defines the <see cref="HorizontalSnapPointsChanged"/> event.
/// </summary>
@ -125,8 +138,23 @@ namespace Avalonia.Controls.Presenters
Size IScrollable.Extent => _logicalScrollable?.Extent ?? default;
Size IScrollable.Viewport => _logicalScrollable?.Viewport ?? default;
public bool AreHorizontalSnapPointsRegular => Panel is IScrollSnapPointsInfo scrollSnapPointsInfo ? scrollSnapPointsInfo.AreHorizontalSnapPointsRegular : false;
public bool AreVerticalSnapPointsRegular => Panel is IScrollSnapPointsInfo scrollSnapPointsInfo ? scrollSnapPointsInfo.AreVerticalSnapPointsRegular : false;
/// <summary>
/// Gets or sets whether the horizontal snap points for the <see cref="ItemsControl"/> are equidistant from each other.
/// </summary>
public bool AreHorizontalSnapPointsRegular
{
get { return GetValue(AreHorizontalSnapPointsRegularProperty); }
set { SetValue(AreHorizontalSnapPointsRegularProperty, value); }
}
/// <summary>
/// Gets or sets whether the vertical snap points for the <see cref="ItemsControl"/> are equidistant from each other.
/// </summary>
public bool AreVerticalSnapPointsRegular
{
get { return GetValue(AreVerticalSnapPointsRegularProperty); }
set { SetValue(AreVerticalSnapPointsRegularProperty, value); }
}
public override sealed void ApplyTemplate()
{
@ -139,9 +167,16 @@ namespace Avalonia.Controls.Presenters
Panel = ItemsPanel.Build();
Panel.SetValue(TemplatedParentProperty, TemplatedParent);
_scrollSnapPointsInfo = Panel as IScrollSnapPointsInfo;
LogicalChildren.Add(Panel);
VisualChildren.Add(Panel);
if (_scrollSnapPointsInfo != null)
{
_scrollSnapPointsInfo.AreVerticalSnapPointsRegular = AreVerticalSnapPointsRegular;
_scrollSnapPointsInfo.AreHorizontalSnapPointsRegular = AreHorizontalSnapPointsRegular;
}
if (Panel is VirtualizingPanel v)
v.Attach(ItemsControl);
else
@ -205,6 +240,16 @@ namespace Avalonia.Controls.Presenters
ResetState();
InvalidateMeasure();
}
else if(change.Property == AreHorizontalSnapPointsRegularProperty)
{
if (_scrollSnapPointsInfo != null)
_scrollSnapPointsInfo.AreHorizontalSnapPointsRegular = AreHorizontalSnapPointsRegular;
}
else if (change.Property == AreVerticalSnapPointsRegularProperty)
{
if (_scrollSnapPointsInfo != null)
_scrollSnapPointsInfo.AreVerticalSnapPointsRegular = AreVerticalSnapPointsRegular;
}
}
internal void Refresh()

8
src/Avalonia.Controls/Primitives/IScrollSnapPointsInfo.cs

@ -11,14 +11,14 @@ namespace Avalonia.Controls.Primitives
public interface IScrollSnapPointsInfo
{
/// <summary>
/// Gets a value that indicates whether the horizontal snap points for the container are equidistant from each other.
/// Gets or sets a value that indicates whether the horizontal snap points for the container are equidistant from each other.
/// </summary>
bool AreHorizontalSnapPointsRegular { get; }
bool AreHorizontalSnapPointsRegular { get; set; }
/// <summary>
/// Gets a value that indicates whether the vertical snap points for the container are equidistant from each other.
/// Gets or sets a value that indicates whether the vertical snap points for the container are equidistant from each other.
/// </summary>
bool AreVerticalSnapPointsRegular { get; }
bool AreVerticalSnapPointsRegular { get; set; }
/// <summary>
/// Returns the set of distances between irregular snap points for a specified orientation and alignment.

32
src/Avalonia.Controls/VirtualizingStackPanel.cs

@ -35,7 +35,7 @@ namespace Avalonia.Controls
/// Defines the <see cref="AreVerticalSnapPointsRegular"/> property.
/// </summary>
public static readonly StyledProperty<bool> AreVerticalSnapPointsRegularProperty =
AvaloniaProperty.Register<StackPanel, bool>(nameof(AreVerticalSnapPointsRegular));
AvaloniaProperty.Register<VirtualizingStackPanel, bool>(nameof(AreVerticalSnapPointsRegular));
/// <summary>
/// Defines the <see cref="HorizontalSnapPointsChanged"/> event.
@ -725,7 +725,20 @@ namespace Avalonia.Controls
}
else
{
snapPoint += averageElementSize;
if (snapPoint == 0)
{
switch (snapPointsAlignment)
{
case SnapPointsAlignment.Center:
snapPoint = averageElementSize / 2;
break;
case SnapPointsAlignment.Far:
snapPoint = averageElementSize;
break;
}
}
else
snapPoint += averageElementSize;
}
snapPoints.Add(snapPoint);
@ -759,7 +772,20 @@ namespace Avalonia.Controls
}
else
{
snapPoint += averageElementSize;
if (snapPoint == 0)
{
switch (snapPointsAlignment)
{
case SnapPointsAlignment.Center:
snapPoint = averageElementSize / 2;
break;
case SnapPointsAlignment.Far:
snapPoint = averageElementSize;
break;
}
}
else
snapPoint += averageElementSize;
}
snapPoints.Add(snapPoint);

2
src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml

@ -9,6 +9,8 @@
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}">
<ItemsPresenter Name="PART_ItemsPresenter"
AreVerticalSnapPointsRegular="{TemplateBinding AreVerticalSnapPointsRegular}"
AreHorizontalSnapPointsRegular="{TemplateBinding AreHorizontalSnapPointsRegular}"
ItemsPanel="{TemplateBinding ItemsPanel}"/>
</Border>
</ControlTemplate>

3
src/Avalonia.Themes.Fluent/Controls/ListBox.xaml

@ -19,7 +19,6 @@
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.IsScrollChainingEnabled" Value="True" />
<Setter Property="ScrollViewer.VerticalSnapPointsType" Value="Mandatory" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Template">
<ControlTemplate>
@ -37,6 +36,8 @@
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
<ItemsPresenter Name="PART_ItemsPresenter"
AreVerticalSnapPointsRegular="{TemplateBinding AreVerticalSnapPointsRegular}"
AreHorizontalSnapPointsRegular="{TemplateBinding AreHorizontalSnapPointsRegular}"
ItemsPanel="{TemplateBinding ItemsPanel}"
Margin="{TemplateBinding Padding}"/>
</ScrollViewer>

2
src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml

@ -10,6 +10,8 @@
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ItemsPresenter Name="PART_ItemsPresenter"
AreVerticalSnapPointsRegular="{TemplateBinding AreVerticalSnapPointsRegular}"
AreHorizontalSnapPointsRegular="{TemplateBinding AreHorizontalSnapPointsRegular}"
ItemsPanel="{TemplateBinding ItemsPanel}" />
</Border>
</ControlTemplate>

6
src/Avalonia.Themes.Simple/Controls/ListBox.xaml

@ -20,9 +20,13 @@
Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
VerticalSnapPointsType="{TemplateBinding (ScrollViewer.VerticalSnapPointsType)}"
HorizontalSnapPointsType="{TemplateBinding (ScrollViewer.HorizontalSnapPointsType)}">
<ItemsPresenter Name="PART_ItemsPresenter"
Margin="{TemplateBinding Padding}"
AreVerticalSnapPointsRegular="{TemplateBinding AreVerticalSnapPointsRegular}"
AreHorizontalSnapPointsRegular="{TemplateBinding AreHorizontalSnapPointsRegular}"
ItemsPanel="{TemplateBinding ItemsPanel}" />
</ScrollViewer>
</Border>

Loading…
Cancel
Save