Browse Source

Merge branch 'master' into release/0.9

pull/3102/head
danwalmsley 7 years ago
committed by GitHub
parent
commit
17680a1783
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      src/Avalonia.Base/AvaloniaObjectExtensions.cs
  2. 50
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  3. 4
      src/Avalonia.Controls.DataGrid/DataGridCell.cs
  4. 2
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  5. 8
      src/Avalonia.Controls.DataGrid/DataGridRow.cs
  6. 4
      src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs
  7. 18
      src/Avalonia.Controls/AutoCompleteBox.cs
  8. 23
      src/Avalonia.Controls/Calendar/Calendar.cs
  9. 16
      src/Avalonia.Controls/Calendar/DatePicker.cs
  10. 12
      src/Avalonia.Controls/Carousel.cs
  11. 4
      src/Avalonia.Controls/ComboBox.cs
  12. 2
      src/Avalonia.Controls/ContentControl.cs
  13. 2
      src/Avalonia.Controls/DataValidationErrors.cs
  14. 2
      src/Avalonia.Controls/Decorator.cs
  15. 2
      src/Avalonia.Controls/Expander.cs
  16. 4
      src/Avalonia.Controls/ItemsControl.cs
  17. 8
      src/Avalonia.Controls/LayoutTransformControl.cs
  18. 2
      src/Avalonia.Controls/MenuBase.cs
  19. 12
      src/Avalonia.Controls/MenuItem.cs
  20. 4
      src/Avalonia.Controls/Presenters/CarouselPresenter.cs
  21. 6
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  22. 2
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  23. 2
      src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
  24. 6
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  25. 2
      src/Avalonia.Controls/Primitives/HeaderedContentControl.cs
  26. 2
      src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs
  27. 2
      src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs
  28. 4
      src/Avalonia.Controls/Primitives/Popup.cs
  29. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  30. 4
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  31. 6
      src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
  32. 2
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  33. 6
      src/Avalonia.Controls/Primitives/Thumb.cs
  34. 6
      src/Avalonia.Controls/Primitives/Track.cs
  35. 5
      src/Avalonia.Controls/Primitives/UniformGrid.cs
  36. 5
      src/Avalonia.Controls/ProgressBar.cs
  37. 4
      src/Avalonia.Controls/ScrollViewer.cs
  38. 6
      src/Avalonia.Controls/Slider.cs
  39. 4
      src/Avalonia.Controls/TabItem.cs
  40. 8
      src/Avalonia.Controls/TopLevel.cs
  41. 2
      src/Avalonia.Controls/TreeViewItem.cs
  42. 4
      src/Avalonia.Controls/Window.cs
  43. 2
      src/Avalonia.Controls/WindowBase.cs
  44. 24
      src/Avalonia.Input/InputElement.cs
  45. 30
      src/Avalonia.Interactivity/RoutedEvent.cs
  46. 2
      src/Avalonia.Styling/StyledElement.cs
  47. 71
      src/Avalonia.Visuals/CornerRadius.cs
  48. 16
      src/Avalonia.Visuals/Matrix.cs
  49. 2
      src/Avalonia.Visuals/Media/Geometry.cs
  50. 28
      src/Avalonia.Visuals/Media/PixelPoint.cs
  51. 26
      src/Avalonia.Visuals/Media/PixelRect.cs
  52. 26
      src/Avalonia.Visuals/Media/PixelSize.cs
  53. 31
      src/Avalonia.Visuals/Point.cs
  54. 42
      src/Avalonia.Visuals/Rect.cs
  55. 12
      src/Avalonia.Visuals/RelativePoint.cs
  56. 14
      src/Avalonia.Visuals/RelativeRect.cs
  57. 30
      src/Avalonia.Visuals/Size.cs
  58. 38
      src/Avalonia.Visuals/Thickness.cs
  59. 11
      src/Avalonia.Visuals/Vector.cs
  60. 13
      src/Avalonia.Visuals/VisualTree/TransformedBounds.cs
  61. 2
      tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs

9
src/Avalonia.Base/AvaloniaObjectExtensions.cs

@ -192,9 +192,9 @@ namespace Avalonia
{
return observable.Subscribe(e =>
{
if (e.Sender is TTarget)
if (e.Sender is TTarget target)
{
action((TTarget)e.Sender, e);
action(target, e);
}
});
}
@ -207,6 +207,7 @@ namespace Avalonia
/// <param name="observable">The property changed observable.</param>
/// <param name="handler">Given a TTarget, returns the handler.</param>
/// <returns>A disposable that can be used to terminate the subscription.</returns>
[Obsolete("Use overload taking Action<TTarget, AvaloniaPropertyChangedEventArgs>.")]
public static IDisposable AddClassHandler<TTarget>(
this IObservable<AvaloniaPropertyChangedEventArgs> observable,
Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler)
@ -238,9 +239,7 @@ namespace Avalonia
Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler)
where TTarget : class
{
var target = e.Sender as TTarget;
if (target != null)
if (e.Sender is TTarget target)
{
handler(target)(e);
}

50
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -723,29 +723,29 @@ namespace Avalonia.Controls
PseudoClass<DataGrid, bool>(IsValidProperty, x => !x, ":invalid");
ItemsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnItemsPropertyChanged);
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnCanUserResizeColumnsChanged);
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnColumnWidthChanged);
RowBackgroundProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowBackgroundChanged);
AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowBackgroundChanged);
FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>(x => x.OnFrozenColumnCountChanged);
GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>(x => x.OnGridLinesVisibilityChanged);
HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>(x => x.OnHeadersVisibilityChanged);
HorizontalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>(x => x.OnHorizontalGridLinesBrushChanged);
IsReadOnlyProperty.Changed.AddClassHandler<DataGrid>(x => x.OnIsReadOnlyChanged);
MaxColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnMaxColumnWidthChanged);
MinColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnMinColumnWidthChanged);
RowHeightProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowHeightChanged);
RowHeaderWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowHeaderWidthChanged);
SelectionModeProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectionModeChanged);
VerticalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>(x => x.OnVerticalGridLinesBrushChanged);
SelectedIndexProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectedIndexChanged);
SelectedItemProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectedItemChanged);
IsEnabledProperty.Changed.AddClassHandler<DataGrid>(x => x.DataGrid_IsEnabledChanged);
AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler<DataGrid>(x => x.OnAreRowGroupHeadersFrozenChanged);
RowDetailsTemplateProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowDetailsTemplateChanged);
RowDetailsVisibilityModeProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowDetailsVisibilityModeChanged);
AutoGenerateColumnsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnAutoGenerateColumnsChanged);
ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e));
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e));
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e));
RowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnFrozenColumnCountChanged(e));
GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnGridLinesVisibilityChanged(e));
HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHeadersVisibilityChanged(e));
HorizontalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHorizontalGridLinesBrushChanged(e));
IsReadOnlyProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnIsReadOnlyChanged(e));
MaxColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnMaxColumnWidthChanged(e));
MinColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnMinColumnWidthChanged(e));
RowHeightProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowHeightChanged(e));
RowHeaderWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowHeaderWidthChanged(e));
SelectionModeProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectionModeChanged(e));
VerticalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnVerticalGridLinesBrushChanged(e));
SelectedIndexProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectedIndexChanged(e));
SelectedItemProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectedItemChanged(e));
IsEnabledProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.DataGrid_IsEnabledChanged(e));
AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnAreRowGroupHeadersFrozenChanged(e));
RowDetailsTemplateProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowDetailsTemplateChanged(e));
RowDetailsVisibilityModeProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowDetailsVisibilityModeChanged(e));
AutoGenerateColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnAutoGenerateColumnsChanged(e));
}
/// <summary>
@ -3533,7 +3533,7 @@ namespace Avalonia.Controls
if (AreColumnHeadersVisible &&
_vScrollBar != null && _vScrollBar.IsVisible)
{
_topRightCornerHeader.IsVisible = true; ;
_topRightCornerHeader.IsVisible = true;
}
else
{
@ -5594,7 +5594,7 @@ namespace Avalonia.Controls
{
// This will trigger a call to this method via Cells_SizeChanged for
// which no processing is needed.
_vScrollBar.IsVisible = true; ;
_vScrollBar.IsVisible = true;
if (_vScrollBar.DesiredSize.Width == 0)
{
// We need to know the width for the rest of layout to work correctly so measure it now

4
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
static DataGridCell()
{
PointerPressedEvent.AddClassHandler<DataGridCell>(
x => x.DataGridCell_PointerPressed, handledEventsToo: true);
(x,e) => x.DataGridCell_PointerPressed(e), handledEventsToo: true);
}
public DataGridCell()
{ }
@ -219,4 +219,4 @@ namespace Avalonia.Controls
}
}
}
}
}

2
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -67,7 +67,7 @@ namespace Avalonia.Controls
static DataGridColumnHeader()
{
AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>(x => x.OnAreSeparatorsVisibleChanged);
AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>((x,e) => x.OnAreSeparatorsVisibleChanged(e));
}
/// <summary>

8
src/Avalonia.Controls.DataGrid/DataGridRow.cs

@ -116,10 +116,10 @@ namespace Avalonia.Controls
static DataGridRow()
{
HeaderProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnHeaderChanged);
DetailsTemplateProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnDetailsTemplateChanged);
AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnAreDetailsVisibleChanged);
PointerPressedEvent.AddClassHandler<DataGridRow>(x => x.DataGridRow_PointerPressed, handledEventsToo: true);
HeaderProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnHeaderChanged(e));
DetailsTemplateProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnDetailsTemplateChanged(e));
AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnAreDetailsVisibleChanged(e));
PointerPressedEvent.AddClassHandler<DataGridRow>((x, e) => x.DataGridRow_PointerPressed(e), handledEventsToo: true);
}
/// <summary>

4
src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs

@ -109,7 +109,7 @@ namespace Avalonia.Controls
static DataGridRowGroupHeader()
{
SublevelIndentProperty.Changed.AddClassHandler<DataGridRowGroupHeader>(x => x.OnSublevelIndentChanged);
SublevelIndentProperty.Changed.AddClassHandler<DataGridRowGroupHeader>((x,e) => x.OnSublevelIndentChanged(e));
}
/// <summary>
@ -446,4 +446,4 @@ namespace Avalonia.Controls
}
}
}
}

18
src/Avalonia.Controls/AutoCompleteBox.cs

@ -805,15 +805,15 @@ namespace Avalonia.Controls
{
FocusableProperty.OverrideDefaultValue<AutoCompleteBox>(true);
MinimumPopulateDelayProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnMinimumPopulateDelayChanged);
IsDropDownOpenProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnIsDropDownOpenChanged);
SelectedItemProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnSelectedItemPropertyChanged);
TextProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnTextPropertyChanged);
SearchTextProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnSearchTextPropertyChanged);
FilterModeProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnFilterModePropertyChanged);
ItemFilterProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnItemFilterPropertyChanged);
ItemsProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnItemsPropertyChanged);
IsEnabledProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnControlIsEnabledChanged);
MinimumPopulateDelayProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnMinimumPopulateDelayChanged(e));
IsDropDownOpenProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnIsDropDownOpenChanged(e));
SelectedItemProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnSelectedItemPropertyChanged(e));
TextProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnTextPropertyChanged(e));
SearchTextProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnSearchTextPropertyChanged(e));
FilterModeProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnFilterModePropertyChanged(e));
ItemFilterProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnItemFilterPropertyChanged(e));
ItemsProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnItemsPropertyChanged(e));
IsEnabledProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnControlIsEnabledChanged(e));
}
/// <summary>

23
src/Avalonia.Controls/Calendar/Calendar.cs

@ -2057,18 +2057,17 @@ namespace Avalonia.Controls
static Calendar()
{
IsEnabledProperty.Changed.AddClassHandler<Calendar>(x => x.OnIsEnabledChanged);
FirstDayOfWeekProperty.Changed.AddClassHandler<Calendar>(x => x.OnFirstDayOfWeekChanged);
IsTodayHighlightedProperty.Changed.AddClassHandler<Calendar>(x => x.OnIsTodayHighlightedChanged);
DisplayModeProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayModePropertyChanged);
SelectionModeProperty.Changed.AddClassHandler<Calendar>(x => x.OnSelectionModeChanged);
SelectedDateProperty.Changed.AddClassHandler<Calendar>(x => x.OnSelectedDateChanged);
DisplayDateProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateChanged);
DisplayDateStartProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateStartChanged);
DisplayDateEndProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateEndChanged);
KeyDownEvent.AddClassHandler<Calendar>(x => x.Calendar_KeyDown);
KeyUpEvent.AddClassHandler<Calendar>(x => x.Calendar_KeyUp);
IsEnabledProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnIsEnabledChanged(e));
FirstDayOfWeekProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnFirstDayOfWeekChanged(e));
IsTodayHighlightedProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnIsTodayHighlightedChanged(e));
DisplayModeProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayModePropertyChanged(e));
SelectionModeProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnSelectionModeChanged(e));
SelectedDateProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnSelectedDateChanged(e));
DisplayDateProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateChanged(e));
DisplayDateStartProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateStartChanged(e));
DisplayDateEndProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateEndChanged(e));
KeyDownEvent.AddClassHandler<Calendar>((x,e) => x.Calendar_KeyDown(e));
KeyUpEvent.AddClassHandler<Calendar>((x,e) => x.Calendar_KeyUp(e));
}
/// <summary>

16
src/Avalonia.Controls/Calendar/DatePicker.cs

@ -393,14 +393,14 @@ namespace Avalonia.Controls
{
FocusableProperty.OverrideDefaultValue<DatePicker>(true);
DisplayDateProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateChanged);
DisplayDateStartProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateStartChanged);
DisplayDateEndProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateEndChanged);
IsDropDownOpenProperty.Changed.AddClassHandler<DatePicker>(x => x.OnIsDropDownOpenChanged);
SelectedDateProperty.Changed.AddClassHandler<DatePicker>(x => x.OnSelectedDateChanged);
SelectedDateFormatProperty.Changed.AddClassHandler<DatePicker>(x => x.OnSelectedDateFormatChanged);
CustomDateFormatStringProperty.Changed.AddClassHandler<DatePicker>(x => x.OnCustomDateFormatStringChanged);
TextProperty.Changed.AddClassHandler<DatePicker>(x => x.OnTextChanged);
DisplayDateProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateChanged(e));
DisplayDateStartProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateStartChanged(e));
DisplayDateEndProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateEndChanged(e));
IsDropDownOpenProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnIsDropDownOpenChanged(e));
SelectedDateProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnSelectedDateChanged(e));
SelectedDateFormatProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnSelectedDateFormatChanged(e));
CustomDateFormatStringProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnCustomDateFormatStringChanged(e));
TextProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnTextChanged(e));
}
/// <summary>
/// Initializes a new instance of the

12
src/Avalonia.Controls/Carousel.cs

@ -84,17 +84,5 @@ namespace Avalonia.Controls
--SelectedIndex;
}
}
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
// Ignore key presses.
}
/// <inheritdoc/>
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
// Ignore pointer presses.
}
}
}

4
src/Avalonia.Controls/ComboBox.cs

@ -65,8 +65,8 @@ namespace Avalonia.Controls
{
ItemsPanelProperty.OverrideDefaultValue<ComboBox>(DefaultPanel);
FocusableProperty.OverrideDefaultValue<ComboBox>(true);
SelectedItemProperty.Changed.AddClassHandler<ComboBox>(x => x.SelectedItemChanged);
KeyDownEvent.AddClassHandler<ComboBox>(x => x.OnKeyDown, Interactivity.RoutingStrategies.Tunnel);
SelectedItemProperty.Changed.AddClassHandler<ComboBox>((x,e) => x.SelectedItemChanged(e));
KeyDownEvent.AddClassHandler<ComboBox>((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel);
}
/// <summary>

2
src/Avalonia.Controls/ContentControl.cs

@ -43,7 +43,7 @@ namespace Avalonia.Controls
static ContentControl()
{
ContentProperty.Changed.AddClassHandler<ContentControl>(x => x.ContentChanged);
ContentProperty.Changed.AddClassHandler<ContentControl>((x, e) => x.ContentChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/DataValidationErrors.cs

@ -56,7 +56,7 @@ namespace Avalonia.Controls
{
ErrorsProperty.Changed.Subscribe(ErrorsChanged);
HasErrorsProperty.Changed.Subscribe(HasErrorsChanged);
TemplatedParentProperty.Changed.AddClassHandler<DataValidationErrors>(x => x.OnTemplatedParentChange);
TemplatedParentProperty.Changed.AddClassHandler<DataValidationErrors>((x, e) => x.OnTemplatedParentChange(e));
}
private void OnTemplatedParentChange(AvaloniaPropertyChangedEventArgs e)

2
src/Avalonia.Controls/Decorator.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
static Decorator()
{
AffectsMeasure<Decorator>(ChildProperty, PaddingProperty);
ChildProperty.Changed.AddClassHandler<Decorator>(x => x.ChildChanged);
ChildProperty.Changed.AddClassHandler<Decorator>((x, e) => x.ChildChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Expander.cs

@ -37,7 +37,7 @@ namespace Avalonia.Controls
PseudoClass<Expander>(IsExpandedProperty, ":expanded");
IsExpandedProperty.Changed.AddClassHandler<Expander>(x => x.OnIsExpandedChanged);
IsExpandedProperty.Changed.AddClassHandler<Expander>((x, e) => x.OnIsExpandedChanged(e));
}
public IPageTransition ContentTransition

4
src/Avalonia.Controls/ItemsControl.cs

@ -64,8 +64,8 @@ namespace Avalonia.Controls
/// </summary>
static ItemsControl()
{
ItemsProperty.Changed.AddClassHandler<ItemsControl>(x => x.ItemsChanged);
ItemTemplateProperty.Changed.AddClassHandler<ItemsControl>(x => x.ItemTemplateChanged);
ItemsProperty.Changed.AddClassHandler<ItemsControl>((x, e) => x.ItemsChanged(e));
ItemTemplateProperty.Changed.AddClassHandler<ItemsControl>((x, e) => x.ItemTemplateChanged(e));
}
/// <summary>

8
src/Avalonia.Controls/LayoutTransformControl.cs

@ -28,11 +28,13 @@ namespace Avalonia.Controls
ClipToBoundsProperty.OverrideDefaultValue<LayoutTransformControl>(true);
LayoutTransformProperty.Changed
.AddClassHandler<LayoutTransformControl>(x => x.OnLayoutTransformChanged);
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnLayoutTransformChanged(e));
ChildProperty.Changed
.AddClassHandler<LayoutTransformControl>(x => x.OnChildChanged);
UseRenderTransformProperty.Changed.AddClassHandler<LayoutTransformControl>(x => x.OnUseRenderTransformPropertyChanged);
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnChildChanged(e));
UseRenderTransformProperty.Changed
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnUseRenderTransformPropertyChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/MenuBase.cs

@ -64,7 +64,7 @@ namespace Avalonia.Controls
/// </summary>
static MenuBase()
{
MenuItem.SubmenuOpenedEvent.AddClassHandler<MenuBase>(x => x.OnSubmenuOpened);
MenuItem.SubmenuOpenedEvent.AddClassHandler<MenuBase>((x, e) => x.OnSubmenuOpened(e));
}
/// <summary>

12
src/Avalonia.Controls/MenuItem.cs

@ -102,13 +102,13 @@ namespace Avalonia.Controls
SelectableMixin.Attach<MenuItem>(IsSelectedProperty);
CommandProperty.Changed.Subscribe(CommandChanged);
FocusableProperty.OverrideDefaultValue<MenuItem>(true);
HeaderProperty.Changed.AddClassHandler<MenuItem>(x => x.HeaderChanged);
IconProperty.Changed.AddClassHandler<MenuItem>(x => x.IconChanged);
IsSelectedProperty.Changed.AddClassHandler<MenuItem>(x => x.IsSelectedChanged);
HeaderProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.HeaderChanged(e));
IconProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.IconChanged(e));
IsSelectedProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.IsSelectedChanged(e));
ItemsPanelProperty.OverrideDefaultValue<MenuItem>(DefaultPanel);
ClickEvent.AddClassHandler<MenuItem>(x => x.OnClick);
SubmenuOpenedEvent.AddClassHandler<MenuItem>(x => x.OnSubmenuOpened);
IsSubMenuOpenProperty.Changed.AddClassHandler<MenuItem>(x => x.SubMenuOpenChanged);
ClickEvent.AddClassHandler<MenuItem>((x, e) => x.OnClick(e));
SubmenuOpenedEvent.AddClassHandler<MenuItem>((x, e) => x.OnSubmenuOpened(e));
IsSubMenuOpenProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.SubMenuOpenChanged(e));
}
public MenuItem()

4
src/Avalonia.Controls/Presenters/CarouselPresenter.cs

@ -46,8 +46,8 @@ namespace Avalonia.Controls.Presenters
/// </summary>
static CarouselPresenter()
{
IsVirtualizedProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.IsVirtualizedChanged);
SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.SelectedIndexChanged);
IsVirtualizedProperty.Changed.AddClassHandler<CarouselPresenter>((x, e) => x.IsVirtualizedChanged(e));
SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>((x, e) => x.SelectedIndexChanged(e));
}
/// <summary>

6
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -94,9 +94,9 @@ namespace Avalonia.Controls.Presenters
{
AffectsRender<ContentPresenter>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure<ContentPresenter>(BorderThicknessProperty, PaddingProperty);
ContentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged);
ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged);
TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.TemplatedParentChanged);
ContentProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.ContentChanged(e));
ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.ContentChanged(e));
TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.TemplatedParentChanged(e));
}
/// <summary>

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

@ -35,7 +35,7 @@ namespace Avalonia.Controls.Presenters
KeyboardNavigationMode.Once);
VirtualizationModeProperty.Changed
.AddClassHandler<ItemsPresenter>(x => x.VirtualizationModeChanged);
.AddClassHandler<ItemsPresenter>((x, e) => x.VirtualizationModeChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

@ -45,7 +45,7 @@ namespace Avalonia.Controls.Presenters
/// </summary>
static ItemsPresenterBase()
{
TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenterBase>(x => x.TemplatedParentChanged);
TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenterBase>((x,e) => x.TemplatedParentChanged(e));
}
/// <summary>

6
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -73,7 +73,7 @@ namespace Avalonia.Controls.Presenters
static ScrollContentPresenter()
{
ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true);
ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>(x => x.ChildChanged);
ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>((x, e) => x.ChildChanged(e));
AffectsArrange<ScrollContentPresenter>(OffsetProperty);
}
@ -246,7 +246,7 @@ namespace Avalonia.Controls.Presenters
if (isLogical)
_activeLogicalGestureScrolls?.TryGetValue(e.Id, out delta);
delta += e.Delta;
if (Extent.Height > Viewport.Height)
{
double dy;
@ -293,7 +293,7 @@ namespace Avalonia.Controls.Presenters
}
}
private void OnScrollGestureEnded(object sender, ScrollGestureEndedEventArgs e)
private void OnScrollGestureEnded(object sender, ScrollGestureEndedEventArgs e)
=> _activeLogicalGestureScrolls?.Remove(e.Id);
/// <inheritdoc/>

2
src/Avalonia.Controls/Primitives/HeaderedContentControl.cs

@ -30,7 +30,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static HeaderedContentControl()
{
ContentProperty.Changed.AddClassHandler<HeaderedContentControl>(x => x.HeaderChanged);
ContentProperty.Changed.AddClassHandler<HeaderedContentControl>((x, e) => x.HeaderChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static HeaderedItemsControl()
{
HeaderProperty.Changed.AddClassHandler<HeaderedItemsControl>(x => x.HeaderChanged);
HeaderProperty.Changed.AddClassHandler<HeaderedItemsControl>((x, e) => x.HeaderChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static HeaderedSelectingItemsControl()
{
HeaderProperty.Changed.AddClassHandler<HeaderedSelectingItemsControl>(x => x.HeaderChanged);
HeaderProperty.Changed.AddClassHandler<HeaderedSelectingItemsControl>((x, e) => x.HeaderChanged(e));
}
/// <summary>

4
src/Avalonia.Controls/Primitives/Popup.cs

@ -93,8 +93,8 @@ namespace Avalonia.Controls.Primitives
static Popup()
{
IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false);
ChildProperty.Changed.AddClassHandler<Popup>(x => x.ChildChanged);
IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged);
ChildProperty.Changed.AddClassHandler<Popup>((x, e) => x.ChildChanged(e));
IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged(e));
}
public Popup()

2
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -17,7 +17,7 @@ namespace Avalonia.Controls.Primitives
/// <summary>
/// The root window of a <see cref="Popup"/>.
/// </summary>
public class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost
public sealed class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost
{
private readonly TopLevel _parent;
private PopupPositionerParameters _positionerParameters;

4
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -58,8 +58,8 @@ namespace Avalonia.Controls.Primitives
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragComplete, RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>((x, e) => x.OnThumbDragComplete(e), RoutingStrategies.Bubble);
}
/// <summary>

6
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@ -119,7 +119,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static SelectingItemsControl()
{
IsSelectedChangedEvent.AddClassHandler<SelectingItemsControl>(x => x.ContainerSelectionChanged);
IsSelectedChangedEvent.AddClassHandler<SelectingItemsControl>((x, e) => x.ContainerSelectionChanged(e));
}
/// <summary>
@ -1088,8 +1088,8 @@ namespace Avalonia.Controls.Primitives
}
else
{
SelectedIndex = _updateSelectedIndex != int.MinValue ?
_updateSelectedIndex :
SelectedIndex = _updateSelectedIndex != int.MinValue ?
_updateSelectedIndex :
AlwaysSelected ? 0 : -1;
}
}

2
src/Avalonia.Controls/Primitives/TemplatedControl.cs

@ -99,7 +99,7 @@ namespace Avalonia.Controls.Primitives
static TemplatedControl()
{
ClipToBoundsProperty.OverrideDefaultValue<TemplatedControl>(true);
TemplateProperty.Changed.AddClassHandler<TemplatedControl>(x => x.OnTemplateChanged);
TemplateProperty.Changed.AddClassHandler<TemplatedControl>((x, e) => x.OnTemplateChanged(e));
}
/// <summary>

6
src/Avalonia.Controls/Primitives/Thumb.cs

@ -22,9 +22,9 @@ namespace Avalonia.Controls.Primitives
static Thumb()
{
DragStartedEvent.AddClassHandler<Thumb>(x => x.OnDragStarted, RoutingStrategies.Bubble);
DragDeltaEvent.AddClassHandler<Thumb>(x => x.OnDragDelta, RoutingStrategies.Bubble);
DragCompletedEvent.AddClassHandler<Thumb>(x => x.OnDragCompleted, RoutingStrategies.Bubble);
DragStartedEvent.AddClassHandler<Thumb>((x,e) => x.OnDragStarted(e), RoutingStrategies.Bubble);
DragDeltaEvent.AddClassHandler<Thumb>((x, e) => x.OnDragDelta(e), RoutingStrategies.Bubble);
DragCompletedEvent.AddClassHandler<Thumb>((x, e) => x.OnDragCompleted(e), RoutingStrategies.Bubble);
}
public event EventHandler<VectorEventArgs> DragStarted

6
src/Avalonia.Controls/Primitives/Track.cs

@ -48,9 +48,9 @@ namespace Avalonia.Controls.Primitives
{
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
ThumbProperty.Changed.AddClassHandler<Track>(x => x.ThumbChanged);
IncreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged);
DecreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged);
ThumbProperty.Changed.AddClassHandler<Track>((x,e) => x.ThumbChanged(e));
IncreaseButtonProperty.Changed.AddClassHandler<Track>((x, e) => x.ButtonChanged(e));
DecreaseButtonProperty.Changed.AddClassHandler<Track>((x, e) => x.ButtonChanged(e));
AffectsArrange<Track>(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty);
}

5
src/Avalonia.Controls/Primitives/UniformGrid.cs

@ -28,6 +28,11 @@ namespace Avalonia.Controls.Primitives
private int _rows;
private int _columns;
static UniformGrid()
{
AffectsMeasure<UniformGrid>(RowsProperty, ColumnsProperty, FirstColumnProperty);
}
/// <summary>
/// Specifies the row count. If set to 0, row count will be calculated automatically.
/// </summary>

5
src/Avalonia.Controls/ProgressBar.cs

@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Controls.Primitives;
using Avalonia.Layout;
@ -38,8 +39,8 @@ namespace Avalonia.Controls
PseudoClass<ProgressBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
PseudoClass<ProgressBar>(IsIndeterminateProperty, ":indeterminate");
ValueProperty.Changed.AddClassHandler<ProgressBar>(x => x.UpdateIndicatorWhenPropChanged);
IsIndeterminateProperty.Changed.AddClassHandler<ProgressBar>(x => x.UpdateIndicatorWhenPropChanged);
ValueProperty.Changed.AddClassHandler<ProgressBar>((x, e) => x.UpdateIndicatorWhenPropChanged(e));
IsIndeterminateProperty.Changed.AddClassHandler<ProgressBar>((x, e) => x.UpdateIndicatorWhenPropChanged(e));
}
public bool IsIndeterminate

4
src/Avalonia.Controls/ScrollViewer.cs

@ -163,8 +163,8 @@ namespace Avalonia.Controls
{
AffectsValidation(ExtentProperty, OffsetProperty);
AffectsValidation(ViewportProperty, OffsetProperty);
HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged);
VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged);
HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>((x, e) => x.ScrollBarVisibilityChanged(e));
VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>((x, e) => x.ScrollBarVisibilityChanged(e));
}
/// <summary>

6
src/Avalonia.Controls/Slider.cs

@ -45,9 +45,9 @@ namespace Avalonia.Controls
OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragStartedEvent.AddClassHandler<Slider>(x => x.OnThumbDragStarted, RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>(x => x.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>(x => x.OnThumbDragCompleted, RoutingStrategies.Bubble);
Thumb.DragStartedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble);
}
/// <summary>

4
src/Avalonia.Controls/TabItem.cs

@ -30,8 +30,8 @@ namespace Avalonia.Controls
{
SelectableMixin.Attach<TabItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue(typeof(TabItem), true);
IsSelectedProperty.Changed.AddClassHandler<TabItem>(x => x.UpdateSelectedContent);
DataContextProperty.Changed.AddClassHandler<TabItem>(x => x.UpdateHeader);
IsSelectedProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateSelectedContent(e));
DataContextProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateHeader(e));
}
/// <summary>

8
src/Avalonia.Controls/TopLevel.cs

@ -271,7 +271,7 @@ namespace Avalonia.Controls
{
(this as IInputRoot).MouseDevice?.TopLevelClosed(this);
PlatformImpl = null;
Closed?.Invoke(this, EventArgs.Empty);
OnClosed(EventArgs.Empty);
Renderer?.Dispose();
Renderer = null;
}
@ -317,6 +317,12 @@ namespace Avalonia.Controls
/// <param name="e">The event args.</param>
protected virtual void OnOpened(EventArgs e) => Opened?.Invoke(this, e);
/// <summary>
/// Raises the <see cref="Closed"/> event.
/// </summary>
/// <param name="e">The event args.</param>
protected virtual void OnClosed(EventArgs e) => Closed?.Invoke(this, e);
/// <summary>
/// Tries to get a service from an <see cref="IAvaloniaDependencyResolver"/>, logging a
/// warning if not found.

2
src/Avalonia.Controls/TreeViewItem.cs

@ -54,7 +54,7 @@ namespace Avalonia.Controls
SelectableMixin.Attach<TreeViewItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue<TreeViewItem>(true);
ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>(x => x.OnRequestBringIntoView);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>((x, e) => x.OnRequestBringIntoView(e));
}
/// <summary>

4
src/Avalonia.Controls/Window.cs

@ -557,7 +557,7 @@ namespace Avalonia.Controls
return result;
}
protected override void HandleClosed()
protected sealed override void HandleClosed()
{
RaiseEvent(new RoutedEventArgs(WindowClosedEvent));
@ -565,7 +565,7 @@ namespace Avalonia.Controls
}
/// <inheritdoc/>
protected override void HandleResized(Size clientSize)
protected sealed override void HandleResized(Size clientSize)
{
if (!AutoSizing)
{

2
src/Avalonia.Controls/WindowBase.cs

@ -47,7 +47,7 @@ namespace Avalonia.Controls
static WindowBase()
{
IsVisibleProperty.OverrideDefaultValue<WindowBase>(false);
IsVisibleProperty.Changed.AddClassHandler<WindowBase>(x => x.IsVisibleChanged);
IsVisibleProperty.Changed.AddClassHandler<WindowBase>((x,e) => x.IsVisibleChanged(e));
TopmostProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue));

24
src/Avalonia.Input/InputElement.cs

@ -169,18 +169,18 @@ namespace Avalonia.Input
{
IsEnabledProperty.Changed.Subscribe(IsEnabledChanged);
GotFocusEvent.AddClassHandler<InputElement>(x => x.OnGotFocus);
LostFocusEvent.AddClassHandler<InputElement>(x => x.OnLostFocus);
KeyDownEvent.AddClassHandler<InputElement>(x => x.OnKeyDown);
KeyUpEvent.AddClassHandler<InputElement>(x => x.OnKeyUp);
TextInputEvent.AddClassHandler<InputElement>(x => x.OnTextInput);
PointerEnterEvent.AddClassHandler<InputElement>(x => x.OnPointerEnterCore);
PointerLeaveEvent.AddClassHandler<InputElement>(x => x.OnPointerLeaveCore);
PointerMovedEvent.AddClassHandler<InputElement>(x => x.OnPointerMoved);
PointerPressedEvent.AddClassHandler<InputElement>(x => x.OnPointerPressed);
PointerReleasedEvent.AddClassHandler<InputElement>(x => x.OnPointerReleased);
PointerCaptureLostEvent.AddClassHandler<InputElement>(x => x.OnPointerCaptureLost);
PointerWheelChangedEvent.AddClassHandler<InputElement>(x => x.OnPointerWheelChanged);
GotFocusEvent.AddClassHandler<InputElement>((x, e) => x.OnGotFocus(e));
LostFocusEvent.AddClassHandler<InputElement>((x, e) => x.OnLostFocus(e));
KeyDownEvent.AddClassHandler<InputElement>((x, e) => x.OnKeyDown(e));
KeyUpEvent.AddClassHandler<InputElement>((x, e) => x.OnKeyUp(e));
TextInputEvent.AddClassHandler<InputElement>((x, e) => x.OnTextInput(e));
PointerEnterEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerEnterCore(e));
PointerLeaveEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerLeaveCore(e));
PointerMovedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerMoved(e));
PointerPressedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerPressed(e));
PointerReleasedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerReleased(e));
PointerCaptureLostEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerCaptureLost(e));
PointerWheelChangedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerWheelChanged(e));
PseudoClass<InputElement, bool>(IsEffectivelyEnabledProperty, x => !x, ":disabled");
PseudoClass<InputElement>(IsFocusedProperty, ":focus");

30
src/Avalonia.Interactivity/RoutedEvent.cs

@ -113,24 +113,38 @@ namespace Avalonia.Interactivity
Contract.Requires<ArgumentNullException>(ownerType != null);
}
[Obsolete("Use overload taking Action<TTarget, TEventArgs>.")]
public IDisposable AddClassHandler<TTarget>(
Func<TTarget, Action<TEventArgs>> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false)
where TTarget : class, IInteractive
where TTarget : class, IInteractive
{
EventHandler<RoutedEventArgs> adapter = (sender, e) =>
void Adapter(object sender, RoutedEventArgs e)
{
var target = sender as TTarget;
var args = e as TEventArgs;
if (target != null && args != null)
if (sender is TTarget target && e is TEventArgs args)
{
handler(target)(args);
}
};
}
return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
}
public IDisposable AddClassHandler<TTarget>(
Action<TTarget, TEventArgs> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false) where TTarget : class, IInteractive
{
void Adapter(object sender, RoutedEventArgs e)
{
if (sender is TTarget target && e is TEventArgs args)
{
handler(target, args);
}
}
return AddClassHandler(typeof(TTarget), adapter, routes, handledEventsToo);
return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
}
}
}

2
src/Avalonia.Styling/StyledElement.cs

@ -73,7 +73,7 @@ namespace Avalonia
/// </summary>
static StyledElement()
{
DataContextProperty.Changed.AddClassHandler<StyledElement>(x => x.OnDataContextChangedCore);
DataContextProperty.Changed.AddClassHandler<StyledElement>((x,e) => x.OnDataContextChangedCore(e));
}
/// <summary>

71
src/Avalonia.Visuals/CornerRadius.cs

@ -8,7 +8,10 @@ using Avalonia.Utilities;
namespace Avalonia
{
public struct CornerRadius
/// <summary>
/// Represents the radii of a rectangle's corners.
/// </summary>
public readonly struct CornerRadius : IEquatable<CornerRadius>
{
static CornerRadius()
{
@ -33,22 +36,59 @@ namespace Avalonia
BottomLeft = bottomLeft;
}
/// <summary>
/// Radius of the top left corner.
/// </summary>
public double TopLeft { get; }
/// <summary>
/// Radius of the top right corner.
/// </summary>
public double TopRight { get; }
/// <summary>
/// Radius of the bottom right corner.
/// </summary>
public double BottomRight { get; }
/// <summary>
/// Radius of the bottom left corner.
/// </summary>
public double BottomLeft { get; }
/// <summary>
/// Gets a value indicating whether all corner radii are set to 0.
/// </summary>
public bool IsEmpty => TopLeft.Equals(0) && IsUniform;
/// <summary>
/// Gets a value indicating whether all corner radii are equal.
/// </summary>
public bool IsUniform => TopLeft.Equals(TopRight) && BottomLeft.Equals(BottomRight) && TopRight.Equals(BottomRight);
public override bool Equals(object obj)
/// <summary>
/// Returns a boolean indicating whether the corner radius is equal to the other given corner radius.
/// </summary>
/// <param name="other">The other corner radius to test equality against.</param>
/// <returns>True if this corner radius is equal to other; False otherwise.</returns>
public bool Equals(CornerRadius other)
{
if (obj is CornerRadius)
{
return this == (CornerRadius)obj;
}
return false;
// ReSharper disable CompareOfFloatsByEqualityOperator
return TopLeft == other.TopLeft &&
TopRight == other.TopRight &&
BottomRight == other.BottomRight &&
BottomLeft == other.BottomLeft;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Returns a boolean indicating whether the given Object is equal to this corner radius instance.
/// </summary>
/// <param name="obj">The Object to compare against.</param>
/// <returns>True if the Object is equal to this corner radius; False otherwise.</returns>
public override bool Equals(object obj) => obj is CornerRadius other && Equals(other);
public override int GetHashCode()
{
return TopLeft.GetHashCode() ^ TopRight.GetHashCode() ^ BottomLeft.GetHashCode() ^ BottomRight.GetHashCode();
@ -61,7 +101,9 @@ namespace Avalonia
public static CornerRadius Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Thickness"))
const string exceptionMessage = "Invalid CornerRadius.";
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage))
{
if (tokenizer.TryReadDouble(out var a))
{
@ -78,21 +120,18 @@ namespace Avalonia
return new CornerRadius(a);
}
throw new FormatException("Invalid CornerRadius.");
throw new FormatException(exceptionMessage);
}
}
public static bool operator ==(CornerRadius cr1, CornerRadius cr2)
public static bool operator ==(CornerRadius left, CornerRadius right)
{
return cr1.TopLeft.Equals(cr2.TopLeft)
&& cr1.TopRight.Equals(cr2.TopRight)
&& cr1.BottomRight.Equals(cr2.BottomRight)
&& cr1.BottomLeft.Equals(cr2.BottomLeft);
return left.Equals(right);
}
public static bool operator !=(CornerRadius cr1, CornerRadius cr2)
public static bool operator !=(CornerRadius left, CornerRadius right)
{
return !(cr1 == cr2);
return !(left == right);
}
}
}

16
src/Avalonia.Visuals/Matrix.cs

@ -10,7 +10,7 @@ namespace Avalonia
/// <summary>
/// A 2x3 matrix.
/// </summary>
public readonly struct Matrix
public readonly struct Matrix : IEquatable<Matrix>
{
private readonly double _m11;
private readonly double _m12;
@ -235,12 +235,14 @@ namespace Avalonia
/// <returns>True if this matrix is equal to other; False otherwise.</returns>
public bool Equals(Matrix other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return _m11 == other.M11 &&
_m12 == other.M12 &&
_m21 == other.M21 &&
_m22 == other.M22 &&
_m31 == other.M31 &&
_m32 == other.M32;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
@ -248,15 +250,7 @@ namespace Avalonia
/// </summary>
/// <param name="obj">The Object to compare against.</param>
/// <returns>True if the Object is equal to this matrix; False otherwise.</returns>
public override bool Equals(object obj)
{
if (!(obj is Matrix))
{
return false;
}
return Equals((Matrix)obj);
}
public override bool Equals(object obj) => obj is Matrix other && Equals(other);
/// <summary>
/// Returns the hash code for this instance.
@ -316,7 +310,7 @@ namespace Avalonia
/// <returns>The <see cref="Matrix"/>.</returns>
public static Matrix Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Matrix"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Matrix."))
{
return new Matrix(
tokenizer.ReadDouble(),

2
src/Avalonia.Visuals/Media/Geometry.cs

@ -22,7 +22,7 @@ namespace Avalonia.Media
static Geometry()
{
TransformProperty.Changed.AddClassHandler<Geometry>(x => x.TransformChanged);
TransformProperty.Changed.AddClassHandler<Geometry>((x,e) => x.TransformChanged(e));
}
/// <summary>

28
src/Avalonia.Visuals/Media/PixelPoint.cs

@ -10,7 +10,7 @@ namespace Avalonia
/// <summary>
/// Represents a point in device pixels.
/// </summary>
public readonly struct PixelPoint
public readonly struct PixelPoint : IEquatable<PixelPoint>
{
/// <summary>
/// A point representing 0,0.
@ -46,7 +46,7 @@ namespace Avalonia
/// <returns>True if the points are equal; otherwise false.</returns>
public static bool operator ==(PixelPoint left, PixelPoint right)
{
return left.X == right.X && left.Y == right.Y;
return left.Equals(right);
}
/// <summary>
@ -120,7 +120,7 @@ namespace Avalonia
/// <returns>The <see cref="PixelPoint"/>.</returns>
public static PixelPoint Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelPoint"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelPoint."))
{
return new PixelPoint(
tokenizer.ReadInt32(),
@ -128,6 +128,18 @@ namespace Avalonia
}
}
/// <summary>
/// Returns a boolean indicating whether the point is equal to the other given point.
/// </summary>
/// <param name="other">The other point to test equality against.</param>
/// <returns>True if this point is equal to other; False otherwise.</returns>
public bool Equals(PixelPoint other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return X == other.X && Y == other.Y;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Checks for equality between a point and an object.
/// </summary>
@ -135,15 +147,7 @@ namespace Avalonia
/// <returns>
/// True if <paramref name="obj"/> is a point that equals the current point.
/// </returns>
public override bool Equals(object obj)
{
if (obj is PixelPoint other)
{
return this == other;
}
return false;
}
public override bool Equals(object obj) => obj is PixelPoint other && Equals(other);
/// <summary>
/// Returns a hash code for a <see cref="PixelPoint"/>.

26
src/Avalonia.Visuals/Media/PixelRect.cs

@ -10,7 +10,7 @@ namespace Avalonia
/// <summary>
/// Represents a rectangle in device pixels.
/// </summary>
public readonly struct PixelRect
public readonly struct PixelRect : IEquatable<PixelRect>
{
/// <summary>
/// An empty rectangle.
@ -148,7 +148,7 @@ namespace Avalonia
/// <returns>True if the rects are equal; otherwise false.</returns>
public static bool operator ==(PixelRect left, PixelRect right)
{
return left.Position == right.Position && left.Size == right.Size;
return left.Equals(right);
}
/// <summary>
@ -196,20 +196,22 @@ namespace Avalonia
rect.Height);
}
/// <summary>
/// Returns a boolean indicating whether the rect is equal to the other given rect.
/// </summary>
/// <param name="other">The other rect to test equality against.</param>
/// <returns>True if this rect is equal to other; False otherwise.</returns>
public bool Equals(PixelRect other)
{
return Position == other.Position && Size == other.Size;
}
/// <summary>
/// Returns a boolean indicating whether the given object is equal to this rectangle.
/// </summary>
/// <param name="obj">The object to compare against.</param>
/// <returns>True if the object is equal to this rectangle; false otherwise.</returns>
public override bool Equals(object obj)
{
if (obj is PixelRect other)
{
return this == other;
}
return false;
}
public override bool Equals(object obj) => obj is PixelRect other && Equals(other);
/// <summary>
/// Returns the hash code for this instance.
@ -432,7 +434,7 @@ namespace Avalonia
/// <returns>The parsed <see cref="PixelRect"/>.</returns>
public static PixelRect Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelRect"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelRect."))
{
return new PixelRect(
tokenizer.ReadInt32(),

26
src/Avalonia.Visuals/Media/PixelSize.cs

@ -10,7 +10,7 @@ namespace Avalonia
/// <summary>
/// Represents a size in device pixels.
/// </summary>
public readonly struct PixelSize
public readonly struct PixelSize : IEquatable<PixelSize>
{
/// <summary>
/// A size representing zero
@ -51,7 +51,7 @@ namespace Avalonia
/// <returns>True if the sizes are equal; otherwise false.</returns>
public static bool operator ==(PixelSize left, PixelSize right)
{
return left.Width == right.Width && left.Height == right.Height;
return left.Equals(right);
}
/// <summary>
@ -72,7 +72,7 @@ namespace Avalonia
/// <returns>The <see cref="PixelSize"/>.</returns>
public static PixelSize Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelSize"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelSize."))
{
return new PixelSize(
tokenizer.ReadInt32(),
@ -80,6 +80,16 @@ namespace Avalonia
}
}
/// <summary>
/// Returns a boolean indicating whether the size is equal to the other given size.
/// </summary>
/// <param name="other">The other size to test equality against.</param>
/// <returns>True if this size is equal to other; False otherwise.</returns>
public bool Equals(PixelSize other)
{
return Width == other.Width && Height == other.Height;
}
/// <summary>
/// Checks for equality between a size and an object.
/// </summary>
@ -87,15 +97,7 @@ namespace Avalonia
/// <returns>
/// True if <paramref name="obj"/> is a size that equals the current size.
/// </returns>
public override bool Equals(object obj)
{
if (obj is PixelSize other)
{
return this == other;
}
return false;
}
public override bool Equals(object obj) => obj is PixelSize other && Equals(other);
/// <summary>
/// Returns a hash code for a <see cref="PixelSize"/>.

31
src/Avalonia.Visuals/Point.cs

@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Globalization;
using Avalonia.Animation.Animators;
using Avalonia.Utilities;
@ -10,7 +11,7 @@ namespace Avalonia
/// <summary>
/// Defines a point.
/// </summary>
public readonly struct Point
public readonly struct Point : IEquatable<Point>
{
static Point()
{
@ -75,7 +76,7 @@ namespace Avalonia
/// <returns>True if the points are equal; otherwise false.</returns>
public static bool operator ==(Point left, Point right)
{
return left.X == right.X && left.Y == right.Y;
return left.Equals(right);
}
/// <summary>
@ -177,7 +178,7 @@ namespace Avalonia
/// <returns>The <see cref="Thickness"/>.</returns>
public static Point Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Point"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Point."))
{
return new Point(
tokenizer.ReadDouble(),
@ -186,6 +187,19 @@ namespace Avalonia
}
}
/// <summary>
/// Returns a boolean indicating whether the point is equal to the other given point.
/// </summary>
/// <param name="other">The other point to test equality against.</param>
/// <returns>True if this point is equal to other; False otherwise.</returns>
public bool Equals(Point other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return _x == other._x &&
_y == other._y;
// ReSharper enable CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Checks for equality between a point and an object.
/// </summary>
@ -193,16 +207,7 @@ namespace Avalonia
/// <returns>
/// True if <paramref name="obj"/> is a point that equals the current point.
/// </returns>
public override bool Equals(object obj)
{
if (obj is Point)
{
var other = (Point)obj;
return X == other.X && Y == other.Y;
}
return false;
}
public override bool Equals(object obj) => obj is Point other && Equals(other);
/// <summary>
/// Returns a hash code for a <see cref="Point"/>.

42
src/Avalonia.Visuals/Rect.cs

@ -11,7 +11,7 @@ namespace Avalonia
/// <summary>
/// Defines a rectangle.
/// </summary>
public readonly struct Rect
public readonly struct Rect : IEquatable<Rect>
{
static Rect()
{
@ -164,7 +164,9 @@ namespace Avalonia
/// <summary>
/// Gets a value that indicates whether the rectangle is empty.
/// </summary>
// ReSharper disable CompareOfFloatsByEqualityOperator
public bool IsEmpty => _width == 0 && _height == 0;
// ReSharper restore CompareOfFloatsByEqualityOperator
/// <summary>
/// Checks for equality between two <see cref="Rect"/>s.
@ -174,7 +176,7 @@ namespace Avalonia
/// <returns>True if the rects are equal; otherwise false.</returns>
public static bool operator ==(Rect left, Rect right)
{
return left.Position == right.Position && left.Size == right.Size;
return left.Equals(right);
}
/// <summary>
@ -297,21 +299,27 @@ namespace Avalonia
Size.Deflate(thickness));
}
/// <summary>
/// Returns a boolean indicating whether the rect is equal to the other given rect.
/// </summary>
/// <param name="other">The other rect to test equality against.</param>
/// <returns>True if this rect is equal to other; False otherwise.</returns>
public bool Equals(Rect other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return _x == other._x &&
_y == other._y &&
_width == other._width &&
_height == other._height;
// ReSharper enable CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Returns a boolean indicating whether the given object is equal to this rectangle.
/// </summary>
/// <param name="obj">The object to compare against.</param>
/// <returns>True if the object is equal to this rectangle; false otherwise.</returns>
public override bool Equals(object obj)
{
if (obj is Rect)
{
var other = (Rect)obj;
return Position == other.Position && Size == other.Size;
}
return false;
}
public override bool Equals(object obj) => obj is Rect other && Equals(other);
/// <summary>
/// Returns the hash code for this instance.
@ -422,10 +430,10 @@ namespace Avalonia
}
else
{
var x1 = Math.Min(this.X, rect.X);
var x2 = Math.Max(this.Right, rect.Right);
var y1 = Math.Min(this.Y, rect.Y);
var y2 = Math.Max(this.Bottom, rect.Bottom);
var x1 = Math.Min(X, rect.X);
var x2 = Math.Max(Right, rect.Right);
var y1 = Math.Min(Y, rect.Y);
var y2 = Math.Max(Bottom, rect.Bottom);
return new Rect(new Point(x1, y1), new Point(x2, y2));
}
@ -493,7 +501,7 @@ namespace Avalonia
/// <returns>The parsed <see cref="Rect"/>.</returns>
public static Rect Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Rect"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Rect."))
{
return new Rect(
tokenizer.ReadDouble(),

12
src/Avalonia.Visuals/RelativePoint.cs

@ -107,10 +107,7 @@ namespace Avalonia
/// </summary>
/// <param name="obj">The other object.</param>
/// <returns>True if the objects are equal, otherwise false.</returns>
public override bool Equals(object obj)
{
return (obj is RelativePoint) && Equals((RelativePoint)obj);
}
public override bool Equals(object obj) => obj is RelativePoint other && Equals(other);
/// <summary>
/// Checks if the <see cref="RelativePoint"/> equals another point.
@ -130,10 +127,7 @@ namespace Avalonia
{
unchecked
{
int hash = 17;
hash = (hash * 23) + Unit.GetHashCode();
hash = (hash * 23) + Point.GetHashCode();
return hash;
return (_point.GetHashCode() * 397) ^ (int)_unit;
}
}
@ -156,7 +150,7 @@ namespace Avalonia
/// <returns>The parsed <see cref="RelativePoint"/>.</returns>
public static RelativePoint Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid RelativePoint"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid RelativePoint."))
{
var x = tokenizer.ReadString();
var y = tokenizer.ReadString();

14
src/Avalonia.Visuals/RelativeRect.cs

@ -116,10 +116,7 @@ namespace Avalonia
/// </summary>
/// <param name="obj">The other object.</param>
/// <returns>True if the objects are equal, otherwise false.</returns>
public override bool Equals(object obj)
{
return (obj is RelativeRect) && Equals((RelativeRect)obj);
}
public override bool Equals(object obj) => obj is RelativeRect other && Equals(other);
/// <summary>
/// Checks if the <see cref="RelativeRect"/> equals another rectangle.
@ -139,10 +136,7 @@ namespace Avalonia
{
unchecked
{
int hash = 17;
hash = (hash * 23) + Unit.GetHashCode();
hash = (hash * 23) + Rect.GetHashCode();
return hash;
return ((int)Unit * 397) ^ Rect.GetHashCode();
}
}
@ -161,7 +155,7 @@ namespace Avalonia
Rect.Width * size.Width,
Rect.Height * size.Height);
}
/// <summary>
/// Parses a <see cref="RelativeRect"/> string.
/// </summary>
@ -169,7 +163,7 @@ namespace Avalonia
/// <returns>The parsed <see cref="RelativeRect"/>.</returns>
public static RelativeRect Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, exceptionMessage: "Invalid RelativeRect"))
using (var tokenizer = new StringTokenizer(s, exceptionMessage: "Invalid RelativeRect."))
{
var x = tokenizer.ReadString();
var y = tokenizer.ReadString();

30
src/Avalonia.Visuals/Size.cs

@ -11,7 +11,7 @@ namespace Avalonia
/// <summary>
/// Defines a size.
/// </summary>
public readonly struct Size
public readonly struct Size : IEquatable<Size>
{
static Size()
{
@ -72,7 +72,7 @@ namespace Avalonia
/// <returns>True if the sizes are equal; otherwise false.</returns>
public static bool operator ==(Size left, Size right)
{
return left._width == right._width && left._height == right._height;
return left.Equals(right);
}
/// <summary>
@ -158,7 +158,7 @@ namespace Avalonia
/// <returns>The <see cref="Size"/>.</returns>
public static Size Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Size"))
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Size."))
{
return new Size(
tokenizer.ReadDouble(),
@ -191,6 +191,19 @@ namespace Avalonia
Math.Max(0, _height - thickness.Top - thickness.Bottom));
}
/// <summary>
/// Returns a boolean indicating whether the size is equal to the other given size.
/// </summary>
/// <param name="other">The other size to test equality against.</param>
/// <returns>True if this size is equal to other; False otherwise.</returns>
public bool Equals(Size other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return _width == other._width &&
_height == other._height;
// ReSharper enable CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Checks for equality between a size and an object.
/// </summary>
@ -198,16 +211,7 @@ namespace Avalonia
/// <returns>
/// True if <paramref name="obj"/> is a size that equals the current size.
/// </returns>
public override bool Equals(object obj)
{
if (obj is Size)
{
var other = (Size)obj;
return Width == other.Width && Height == other.Height;
}
return false;
}
public override bool Equals(object obj) => obj is Size other && Equals(other);
/// <summary>
/// Returns a hash code for a <see cref="Size"/>.

38
src/Avalonia.Visuals/Thickness.cs

@ -3,7 +3,6 @@
using System;
using System.Globalization;
using Avalonia.Animation;
using Avalonia.Animation.Animators;
using Avalonia.Utilities;
@ -12,7 +11,7 @@ namespace Avalonia
/// <summary>
/// Describes the thickness of a frame around a rectangle.
/// </summary>
public readonly struct Thickness
public readonly struct Thickness : IEquatable<Thickness>
{
static Thickness()
{
@ -204,7 +203,9 @@ namespace Avalonia
/// <returns>The <see cref="Thickness"/>.</returns>
public static Thickness Parse(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Thickness"))
const string exceptionMessage = "Invalid Thickness.";
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage))
{
if (tokenizer.TryReadDouble(out var a))
{
@ -221,10 +222,25 @@ namespace Avalonia
return new Thickness(a);
}
throw new FormatException("Invalid Thickness.");
throw new FormatException(exceptionMessage);
}
}
/// <summary>
/// Returns a boolean indicating whether the thickness is equal to the other given point.
/// </summary>
/// <param name="other">The other thickness to test equality against.</param>
/// <returns>True if this thickness is equal to other; False otherwise.</returns>
public bool Equals(Thickness other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return _left == other._left &&
_top == other._top &&
_right == other._right &&
_bottom == other._bottom;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Checks for equality between a thickness and an object.
/// </summary>
@ -232,19 +248,7 @@ namespace Avalonia
/// <returns>
/// True if <paramref name="obj"/> is a size that equals the current size.
/// </returns>
public override bool Equals(object obj)
{
if (obj is Thickness)
{
Thickness other = (Thickness)obj;
return Left == other.Left &&
Top == other.Top &&
Right == other.Right &&
Bottom == other.Bottom;
}
return false;
}
public override bool Equals(object obj) => obj is Thickness other && Equals(other);
/// <summary>
/// Returns a hash code for a <see cref="Thickness"/>.

11
src/Avalonia.Visuals/Vector.cs

@ -11,7 +11,7 @@ namespace Avalonia
/// <summary>
/// Defines a vector.
/// </summary>
public readonly struct Vector
public readonly struct Vector : IEquatable<Vector>
{
static Vector()
{
@ -138,7 +138,6 @@ namespace Avalonia
/// </summary>
/// <param name="other">The other vector.</param>
/// <returns>True if vectors are nearly equal.</returns>
[Pure]
public bool NearlyEquals(Vector other)
{
const float tolerance = float.Epsilon;
@ -146,13 +145,7 @@ namespace Avalonia
return Math.Abs(_x - other._x) < tolerance && Math.Abs(_y - other._y) < tolerance;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
return obj is Vector vector && Equals(vector);
}
public override bool Equals(object obj) => obj is Vector other && Equals(other);
public override int GetHashCode()
{

13
src/Avalonia.Visuals/VisualTree/TransformedBounds.cs

@ -1,13 +1,14 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.VisualTree
{
/// <summary>
/// Holds information about the bounds of a control, together with a transform and a clip.
/// </summary>
public readonly struct TransformedBounds
public readonly struct TransformedBounds : IEquatable<TransformedBounds>
{
/// <summary>
/// Initializes a new instance of the <see cref="TransformedBounds"/> struct.
@ -56,15 +57,7 @@ namespace Avalonia.VisualTree
return Bounds == other.Bounds && Clip == other.Clip && Transform == other.Transform;
}
public override bool Equals(object obj)
{
if (obj is null)
{
return false;
}
return obj is TransformedBounds other && Equals(other);
}
public override bool Equals(object obj) => obj is TransformedBounds other && Equals(other);
public override int GetHashCode()
{

2
tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs

@ -331,7 +331,7 @@ namespace Avalonia.Interactivity.UnitTests
var target = CreateTree(ev, null, 0);
ev.AddClassHandler<TestInteractive>(x => x.ClassHandler, RoutingStrategies.Bubble);
ev.AddClassHandler<TestInteractive>((x, e) => x.ClassHandler(e), RoutingStrategies.Bubble);
var args = new RoutedEventArgs(ev, target);
target.RaiseEvent(args);

Loading…
Cancel
Save