diff --git a/.travis.yml b/.travis.yml index d80d24f32c..b0c0c807cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ mono: - 5.2.0 dotnet: 2.1.200 script: + - sudo apt-get update + - sudo apt-get install castxml - ./build.sh --target "Travis" --configuration "Release" notifications: email: false diff --git a/build.cake b/build.cake index 000cbb1784..d653e9da58 100644 --- a/build.cake +++ b/build.cake @@ -3,8 +3,8 @@ /////////////////////////////////////////////////////////////////////////////// #addin "nuget:?package=NuGet.Core&version=2.14.0" -#tool "nuget:?package=NuGet.CommandLine&version=4.3.0" -#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2017.1.20170613.162720" +#tool "nuget:?package=NuGet.CommandLine&version=4.7.1" +#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.3" /////////////////////////////////////////////////////////////////////////////// // TOOLS diff --git a/samples/ControlCatalog/Pages/ButtonPage.xaml b/samples/ControlCatalog/Pages/ButtonPage.xaml index 38757148ab..a4690e32e1 100644 --- a/samples/ControlCatalog/Pages/ButtonPage.xaml +++ b/samples/ControlCatalog/Pages/ButtonPage.xaml @@ -18,7 +18,7 @@ diff --git a/src/Avalonia.Base/Utilities/MathUtilities.cs b/src/Avalonia.Base/Utilities/MathUtilities.cs index ab21e5fda0..dcb3ef4a2b 100644 --- a/src/Avalonia.Base/Utilities/MathUtilities.cs +++ b/src/Avalonia.Base/Utilities/MathUtilities.cs @@ -1,7 +1,6 @@ // 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. - namespace Avalonia.Utilities { /// @@ -31,5 +30,28 @@ namespace Avalonia.Utilities return val; } } + + /// + /// Clamps a value between a minimum and maximum value. + /// + /// The value. + /// The minimum value. + /// The maximum value. + /// The clamped value. + public static int Clamp(int val, int min, int max) + { + if (val < min) + { + return min; + } + else if (val > max) + { + return max; + } + else + { + return val; + } + } } } diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs index f31a48b2a0..b177dc50cf 100644 --- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs +++ b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs @@ -76,9 +76,23 @@ namespace Avalonia.Controls.Presenters var firstIndex = ItemCount - panel.Children.Count; RecycleContainersForMove(firstIndex - FirstIndex); - panel.PixelOffset = VirtualizingPanel.ScrollDirection == Orientation.Vertical ? - panel.Children[0].Bounds.Height : - panel.Children[0].Bounds.Width; + double pixelOffset; + var child = panel.Children[0]; + + if (child.IsArrangeValid) + { + pixelOffset = VirtualizingPanel.ScrollDirection == Orientation.Vertical ? + child.Bounds.Height : + child.Bounds.Width; + } + else + { + pixelOffset = VirtualizingPanel.ScrollDirection == Orientation.Vertical ? + child.DesiredSize.Height : + child.DesiredSize.Width; + } + + panel.PixelOffset = pixelOffset; } } } @@ -402,6 +416,10 @@ namespace Avalonia.Controls.Presenters var panel = VirtualizingPanel; var generator = Owner.ItemContainerGenerator; var selector = Owner.MemberSelector; + + //validate delta it should never overflow last index or generate index < 0 + delta = MathUtilities.Clamp(delta, -FirstIndex, ItemCount - FirstIndex - panel.Children.Count); + var sign = delta < 0 ? -1 : 1; var count = Math.Min(Math.Abs(delta), panel.Children.Count); var move = count < panel.Children.Count; diff --git a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs new file mode 100644 index 0000000000..04c6f100a6 --- /dev/null +++ b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs @@ -0,0 +1,44 @@ +// 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 Avalonia; +using Avalonia.VisualTree; +using Avalonia.Controls; +using ReactiveUI; + +namespace Avalonia +{ + /// + /// A ReactiveUI UserControl that implements + /// and will activate your ViewModel automatically if it supports activation. + /// + /// ViewModel type. + public class ReactiveUserControl : UserControl, IViewFor where TViewModel : class + { + public static readonly AvaloniaProperty ViewModelProperty = AvaloniaProperty + .Register, TViewModel>(nameof(ViewModel)); + + /// + /// Initializes a new instance of the class. + /// + public ReactiveUserControl() + { + DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel; + } + + /// + /// The ViewModel. + /// + public TViewModel ViewModel + { + get => GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (TViewModel)value; + } + } +} \ No newline at end of file diff --git a/src/Avalonia.ReactiveUI/ReactiveWindow.cs b/src/Avalonia.ReactiveUI/ReactiveWindow.cs new file mode 100644 index 0000000000..bb50a37764 --- /dev/null +++ b/src/Avalonia.ReactiveUI/ReactiveWindow.cs @@ -0,0 +1,44 @@ +// 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 Avalonia; +using Avalonia.VisualTree; +using Avalonia.Controls; +using ReactiveUI; + +namespace Avalonia +{ + /// + /// A ReactiveUI Window that implements + /// and will activate your ViewModel automatically if it supports activation. + /// + /// ViewModel type. + public class ReactiveWindow : Window, IViewFor where TViewModel : class + { + public static readonly AvaloniaProperty ViewModelProperty = AvaloniaProperty + .Register, TViewModel>(nameof(ViewModel)); + + /// + /// Initializes a new instance of the class. + /// + public ReactiveWindow() + { + DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel; + } + + /// + /// The ViewModel. + /// + public TViewModel ViewModel + { + get => GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (TViewModel)value; + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Themes.Default/Accents/BaseLight.xaml b/src/Avalonia.Themes.Default/Accents/BaseLight.xaml index 46767feca0..bf778fcc93 100644 --- a/src/Avalonia.Themes.Default/Accents/BaseLight.xaml +++ b/src/Avalonia.Themes.Default/Accents/BaseLight.xaml @@ -9,34 +9,34 @@ #33119EDA #FFFFFFFF - #FFAAAAAA + #FFAAAAAA #FF888888 - #FF333333 - #FFFFFFFF + #FF333333 + #FFFFFFFF #FFAAAAAA - #FF888888 + #FF888888 #FFF0F0F0 #FFD0D0D0 - #FF808080 + #FF808080 #FF000000 - #FF808080 + #FF808080 #FF086F9E #FFFF0000 - #10FF0000 + #10FF0000 - + - - + + - + - + - + @@ -44,7 +44,7 @@ - + 2 0.5 diff --git a/src/Avalonia.Themes.Default/Button.xaml b/src/Avalonia.Themes.Default/Button.xaml index 94fcce5e0c..698ddec2a8 100644 --- a/src/Avalonia.Themes.Default/Button.xaml +++ b/src/Avalonia.Themes.Default/Button.xaml @@ -1,7 +1,7 @@ diff --git a/src/Avalonia.Themes.Default/CalendarDayButton.xaml b/src/Avalonia.Themes.Default/CalendarDayButton.xaml index 4a971ef0cb..2d79e62a75 100644 --- a/src/Avalonia.Themes.Default/CalendarDayButton.xaml +++ b/src/Avalonia.Themes.Default/CalendarDayButton.xaml @@ -100,10 +100,10 @@ diff --git a/src/Avalonia.Themes.Default/DatePicker.xaml b/src/Avalonia.Themes.Default/DatePicker.xaml index 93bafdb56f..3fb760d35b 100644 --- a/src/Avalonia.Themes.Default/DatePicker.xaml +++ b/src/Avalonia.Themes.Default/DatePicker.xaml @@ -29,7 +29,7 @@ HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" - Background="{DynamicResource ThemeControlLightBrush}" + Background="{DynamicResource ThemeControlLowBrush}" ColumnDefinitions="*,*,*,*" RowDefinitions="23*,19*,19*,19*" ClipToBounds="False"> @@ -47,12 +47,12 @@ Grid.Row="1" Grid.RowSpan="3" BorderThickness="1" - BorderBrush="{DynamicResource ThemeBorderDarkBrush}" + BorderBrush="{DynamicResource ThemeBorderHighBrush}" CornerRadius=".5" /> + Foreground="{DynamicResource ThemeBorderHighBrush}"> - + @@ -123,7 +123,7 @@ diff --git a/src/Avalonia.Themes.Default/DropDown.xaml b/src/Avalonia.Themes.Default/DropDown.xaml index c57d961f4b..451f1c2f23 100644 --- a/src/Avalonia.Themes.Default/DropDown.xaml +++ b/src/Avalonia.Themes.Default/DropDown.xaml @@ -52,6 +52,6 @@ \ No newline at end of file diff --git a/src/Avalonia.Themes.Default/Expander.xaml b/src/Avalonia.Themes.Default/Expander.xaml index d12f704cc4..d63f785e77 100644 --- a/src/Avalonia.Themes.Default/Expander.xaml +++ b/src/Avalonia.Themes.Default/Expander.xaml @@ -89,7 +89,7 @@ - @@ -108,7 +108,7 @@