diff --git a/nukebuild/BuildParameters.cs b/nukebuild/BuildParameters.cs
index 5f8ec7267e..afd1950859 100644
--- a/nukebuild/BuildParameters.cs
+++ b/nukebuild/BuildParameters.cs
@@ -14,13 +14,13 @@ using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
public partial class Build
{
[Parameter("configuration")]
- public string NukeArgConfiguration { get; set; }
+ public string Configuration { get; set; }
[Parameter("skip-tests")]
- public bool NukeArgSkipTests { get; set; }
+ public bool SkipTests { get; set; }
[Parameter("force-nuget-version")]
- public string NukeArgForceNugetVersion { get; set; }
+ public string ForceNugetVersion { get; set; }
public class BuildParameters
{
@@ -64,8 +64,8 @@ public partial class Build
public BuildParameters(Build b)
{
// ARGUMENTS
- Configuration = b.NukeArgConfiguration ?? "Release";
- SkipTests = b.NukeArgSkipTests;
+ Configuration = b.Configuration ?? "Release";
+ SkipTests = b.SkipTests;
// CONFIGURATION
MainRepo = "https://github.com/AvaloniaUI/Avalonia";
@@ -102,7 +102,7 @@ public partial class Build
IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch;
// VERSION
- Version = b.NukeArgForceNugetVersion ?? GetVersion();
+ Version = b.ForceNugetVersion ?? GetVersion();
if (IsRunningOnAzure)
{
diff --git a/parameters.cake b/parameters.cake
deleted file mode 100644
index 4ef7e8e05a..0000000000
--- a/parameters.cake
+++ /dev/null
@@ -1,129 +0,0 @@
-using System.Xml.Linq;
-using System.Linq;
-
-public class Parameters
-{
- public string Configuration { get; private set; }
- public bool SkipTests { get; private set; }
- public string MainRepo { get; private set; }
- public string MasterBranch { get; private set; }
- public string ReleasePlatform { get; private set; }
- public string ReleaseConfiguration { get; private set; }
- public string ReleaseBranchPrefix { get; private set; }
- public string MSBuildSolution { get; private set; }
- public bool IsLocalBuild { get; private set; }
- public bool IsRunningOnUnix { get; private set; }
- public bool IsRunningOnWindows { get; private set; }
- public bool IsRunningOnAppVeyor { get; private set; }
- public bool IsRunningOnAzure { get; private set; }
- public bool IsPullRequest { get; private set; }
- public bool IsMainRepo { get; private set; }
- public bool IsMasterBranch { get; private set; }
- public bool IsReleaseBranch { get; private set; }
- public bool IsTagged { get; private set; }
- public bool IsReleasable { get; private set; }
- public bool IsMyGetRelease { get; private set; }
- public bool IsNuGetRelease { get; private set; }
- public bool PublishTestResults { get; private set; }
- public string Version { get; private set; }
- public DirectoryPath ArtifactsDir { get; private set; }
- public DirectoryPath NugetRoot { get; private set; }
- public DirectoryPath ZipRoot { get; private set; }
- public DirectoryPath BinRoot { get; private set; }
- public DirectoryPath TestResultsRoot { get; private set; }
- public string DirSuffix { get; private set; }
- public DirectoryPathCollection BuildDirs { get; private set; }
- public string FileZipSuffix { get; private set; }
- public FilePath ZipCoreArtifacts { get; private set; }
- public FilePath ZipNuGetArtifacts { get; private set; }
- public DirectoryPath ZipSourceControlCatalogDesktopDirs { get; private set; }
- public FilePath ZipTargetControlCatalogDesktopDirs { get; private set; }
-
- public Parameters(ICakeContext context)
- {
- var buildSystem = context.BuildSystem();
-
- // ARGUMENTS
- Configuration = context.Argument("configuration", "Release");
- SkipTests = context.HasArgument("skip-tests");
-
- // CONFIGURATION
- MainRepo = "https://github.com/AvaloniaUI/Avalonia";
- MasterBranch = "master";
- ReleaseBranchPrefix = "refs/heads/release/";
- ReleaseConfiguration = "Release";
- MSBuildSolution = "./dirs.proj";
-
- // PARAMETERS
- IsLocalBuild = buildSystem.IsLocalBuild;
- IsRunningOnUnix = context.IsRunningOnUnix();
- IsRunningOnWindows = context.IsRunningOnWindows();
- IsRunningOnAppVeyor = buildSystem.AppVeyor.IsRunningOnAppVeyor;
- IsRunningOnAzure = buildSystem.IsRunningOnVSTS || buildSystem.IsRunningOnTFS || context.EnvironmentVariable("LOGNAME") == "vsts";
-
- IsPullRequest = buildSystem.AppVeyor.Environment.PullRequest.IsPullRequest;
- IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, context.EnvironmentVariable("BUILD_REPOSITORY_URI"));
- IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, context.EnvironmentVariable("BUILD_SOURCEBRANCHNAME"));
- IsReleaseBranch = (context.EnvironmentVariable("BUILD_SOURCEBRANCH")??"").StartsWith(ReleaseBranchPrefix, StringComparison.OrdinalIgnoreCase);
- IsTagged = buildSystem.AppVeyor.Environment.Repository.Tag.IsTag
- && !string.IsNullOrWhiteSpace(buildSystem.AppVeyor.Environment.Repository.Tag.Name);
- IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration);
- IsMyGetRelease = !IsTagged && IsReleasable;
- IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch;
-
- // VERSION
- Version = context.Argument("force-nuget-version", GetVersion());
-
- if (IsRunningOnAppVeyor)
- {
- string tagVersion = null;
- if (IsTagged)
- {
- var tag = buildSystem.AppVeyor.Environment.Repository.Tag.Name;
- var nugetReleasePrefix = "nuget-release-";
- IsNuGetRelease = IsTagged && IsReleasable && tag.StartsWith(nugetReleasePrefix);
- if(IsNuGetRelease)
- tagVersion = tag.Substring(nugetReleasePrefix.Length);
- }
- if(tagVersion != null)
- {
- Version = tagVersion;
- }
- else
- {
- // Use AssemblyVersion with Build as version
- Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-beta";
- }
- }
- else if (IsRunningOnAzure)
- {
- if(!IsNuGetRelease)
- {
- // Use AssemblyVersion with Build as version
- Version += "-build" + context.EnvironmentVariable("BUILD_BUILDID") + "-beta";
- }
-
- PublishTestResults = true;
- }
-
- // DIRECTORIES
- ArtifactsDir = (DirectoryPath)context.Directory("./artifacts");
- NugetRoot = ArtifactsDir.Combine("nuget");
- ZipRoot = ArtifactsDir.Combine("zip");
- BinRoot = ArtifactsDir.Combine("bin");
- TestResultsRoot = ArtifactsDir.Combine("test-results");
- BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj");
- DirSuffix = Configuration;
- FileZipSuffix = Version + ".zip";
- ZipCoreArtifacts = ZipRoot.CombineWithFilePath("Avalonia-" + FileZipSuffix);
- ZipNuGetArtifacts = ZipRoot.CombineWithFilePath("Avalonia-NuGet-" + FileZipSuffix);
- ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461");
- ZipTargetControlCatalogDesktopDirs = ZipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + FileZipSuffix);
- }
-
- private static string GetVersion()
- {
- var xdoc = XDocument.Load("./build/SharedVersion.props");
- return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value;
- }
-}
diff --git a/src/Avalonia.Base/Data/Core/ExpressionNode.cs b/src/Avalonia.Base/Data/Core/ExpressionNode.cs
index f2f3ed9bfc..8a2dd46b86 100644
--- a/src/Avalonia.Base/Data/Core/ExpressionNode.cs
+++ b/src/Avalonia.Base/Data/Core/ExpressionNode.cs
@@ -147,6 +147,7 @@ namespace Avalonia.Data.Core
private void StopListening()
{
StopListeningCore();
+ _listening = false;
}
private BindingNotification TargetNullNotification()
diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
index b177dc50cf..f72a65ead2 100644
--- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
+++ b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
@@ -517,7 +517,7 @@ namespace Avalonia.Controls.Presenters
if (index >= 0 && index < ItemCount)
{
- if (index < FirstIndex)
+ if (index <= FirstIndex)
{
newOffset = index;
}
@@ -525,10 +525,6 @@ namespace Avalonia.Controls.Presenters
{
newOffset = index - Math.Ceiling(ViewportValue - 1);
}
- else if (OffsetValue + ViewportValue >= ItemCount)
- {
- newOffset = OffsetValue - 1;
- }
if (newOffset != -1)
{
@@ -546,6 +542,11 @@ namespace Avalonia.Controls.Presenters
{
layoutManager.ExecuteLayoutPass();
+ if (newOffset != -1 && newOffset != OffsetValue)
+ {
+ OffsetValue = newOffset;
+ }
+
if (panel.ScrollDirection == Orientation.Vertical)
{
if (container.Bounds.Y < panel.Bounds.Y || container.Bounds.Bottom > panel.Bounds.Bottom)
diff --git a/src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs b/src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs
index 25f12ffa57..541e8646b1 100644
--- a/src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs
+++ b/src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs
@@ -72,11 +72,7 @@ namespace Avalonia.Styling
///
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
{
- if (!AvaloniaPropertyRegistry.Instance.IsRegistered(control, _property))
- {
- return SelectorMatch.False;
- }
- else if (subscribe)
+ if (subscribe)
{
return new SelectorMatch(control.GetObservable(_property).Select(v => Equals(v ?? string.Empty, _value)));
}
diff --git a/src/Avalonia.Visuals/Matrix.cs b/src/Avalonia.Visuals/Matrix.cs
index cdaaa2b4b4..d083a2aaf8 100644
--- a/src/Avalonia.Visuals/Matrix.cs
+++ b/src/Avalonia.Visuals/Matrix.cs
@@ -293,13 +293,13 @@ namespace Avalonia
/// The inverted matrix.
public Matrix Invert()
{
- if (GetDeterminant() == 0)
+ double d = GetDeterminant();
+
+ if (d == 0)
{
throw new InvalidOperationException("Transform is not invertible.");
}
- double d = GetDeterminant();
-
return new Matrix(
_m22 / d,
-_m12 / d,
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index 6174bc360f..f4eb0e2ea8 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -153,17 +153,24 @@ namespace Avalonia.Win32
public void Resize(Size value)
{
- if (value != ClientSize)
+ int requestedClientWidth = (int)(value.Width * Scaling);
+ int requestedClientHeight = (int)(value.Height * Scaling);
+ UnmanagedMethods.RECT clientRect;
+ UnmanagedMethods.GetClientRect(_hwnd, out clientRect);
+
+ // do comparison after scaling to avoid rounding issues
+ if (requestedClientWidth != clientRect.Width || requestedClientHeight != clientRect.Height)
{
- value *= Scaling;
-
+ UnmanagedMethods.RECT windowRect;
+ UnmanagedMethods.GetWindowRect(_hwnd, out windowRect);
+
UnmanagedMethods.SetWindowPos(
_hwnd,
IntPtr.Zero,
0,
0,
- (int)value.Width,
- (int)value.Height,
+ requestedClientWidth + (windowRect.Width - clientRect.Width),
+ requestedClientHeight + (windowRect.Height - clientRect.Height),
UnmanagedMethods.SetWindowPosFlags.SWP_RESIZE);
}
}
diff --git a/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs b/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs
index c90683959e..f282d1baf3 100644
--- a/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs
+++ b/tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs
@@ -563,6 +563,19 @@ namespace Avalonia.Base.UnitTests.Data.Core
Assert.Null(result.Item2.Target);
}
+ [Fact]
+ public void Should_Not_Throw_Exception_On_Unsubscribe_When_Already_Unsubscribed()
+ {
+ var source = new Class1 { Foo = "foo" };
+ var target = new PropertyAccessorNode("Foo", false);
+ Assert.NotNull(target);
+ target.Target = new WeakReference(source);
+ target.Subscribe(_ => { });
+ target.Unsubscribe();
+ target.Unsubscribe();
+ Assert.True(true);
+ }
+
private interface INext
{
int PropertyChangedSubscriptionCount { get; }
diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
index b992453fb0..7187ea16da 100644
--- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
+++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
@@ -717,6 +717,45 @@ namespace Avalonia.Controls.UnitTests.Presenters
Assert.Equal(10, target.Panel.Children.Count);
}
+ [Fact]
+ public void Scroll_To_Last_Should_Work()
+ {
+ var target = CreateTarget(itemCount: 11);
+ var scroller = (TestScroller)target.Parent;
+
+ scroller.Width = scroller.Height = 100;
+ scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+
+ var last = (target.Items as IList)[10];
+
+ target.ScrollIntoView(last);
+
+ Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
+ Assert.Same(target.Panel.Children[9].DataContext, last);
+ }
+
+ [Fact]
+ public void Second_Scroll_To_Last_Should_Work()
+ {
+ var target = CreateTarget(itemCount: 11);
+ var scroller = (TestScroller)target.Parent;
+
+ scroller.Width = scroller.Height = 100;
+ scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+
+ var last = (target.Items as IList)[10];
+
+ target.ScrollIntoView(last);
+
+ Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
+ Assert.Same(target.Panel.Children[9].DataContext, last);
+
+ target.ScrollIntoView(last);
+
+ Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
+ Assert.Same(target.Panel.Children[9].DataContext, last);
+ }
+
public class Vertical
{
[Fact]
@@ -1090,4 +1129,4 @@ namespace Avalonia.Controls.UnitTests.Presenters
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tools/packages.config b/tools/packages.config
deleted file mode 100644
index 05018882e8..0000000000
--- a/tools/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-