Browse Source

Merge branch 'master' into fixes/1271-orphaned-textblock

pull/1284/head
Steven Kirk 8 years ago
committed by GitHub
parent
commit
cdc590f1a8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      src/Avalonia.Base/AvaloniaObject.cs
  2. 46
      src/Avalonia.Base/PriorityBindingEntry.cs
  3. 12
      src/Avalonia.Controls/Primitives/Track.cs
  4. 28
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Direct.cs
  5. 26
      tests/Avalonia.Controls.UnitTests/Primitives/TrackTests.cs

47
src/Avalonia.Base/AvaloniaObject.cs

@ -339,9 +339,6 @@ namespace Avalonia
var description = GetDescription(source);
var scheduler = AvaloniaLocator.Current.GetService<IScheduler>() ?? ImmediateScheduler.Instance;
source = source.ObserveOn(scheduler);
if (property.IsDirect)
{
if (property.IsReadOnly)
@ -743,29 +740,41 @@ namespace Avalonia
/// <param name="value">The value.</param>
private void SetDirectValue(AvaloniaProperty property, object value)
{
var notification = value as BindingNotification;
if (notification != null)
void Set()
{
notification.LogIfError(this, property);
value = notification.Value;
}
var notification = value as BindingNotification;
if (notification == null || notification.ErrorType == BindingErrorType.Error || notification.HasValue)
{
var metadata = (IDirectPropertyMetadata)property.GetMetadata(GetType());
var accessor = (IDirectPropertyAccessor)GetRegistered(property);
var finalValue = value == AvaloniaProperty.UnsetValue ?
metadata.UnsetValue : value;
if (notification != null)
{
notification.LogIfError(this, property);
value = notification.Value;
}
LogPropertySet(property, value, BindingPriority.LocalValue);
if (notification == null || notification.ErrorType == BindingErrorType.Error || notification.HasValue)
{
var metadata = (IDirectPropertyMetadata)property.GetMetadata(GetType());
var accessor = (IDirectPropertyAccessor)GetRegistered(property);
var finalValue = value == AvaloniaProperty.UnsetValue ?
metadata.UnsetValue : value;
accessor.SetValue(this, finalValue);
LogPropertySet(property, value, BindingPriority.LocalValue);
accessor.SetValue(this, finalValue);
}
if (notification != null)
{
UpdateDataValidation(property, notification);
}
}
if (notification != null)
if (Dispatcher.UIThread.CheckAccess())
{
Set();
}
else
{
UpdateDataValidation(property, notification);
Dispatcher.UIThread.InvokeAsync(Set);
}
}

46
src/Avalonia.Base/PriorityBindingEntry.cs

@ -3,6 +3,7 @@
using System;
using Avalonia.Data;
using Avalonia.Threading;
namespace Avalonia
{
@ -92,33 +93,50 @@ namespace Avalonia
private void ValueChanged(object value)
{
_owner.Owner.Owner?.VerifyAccess();
var notification = value as BindingNotification;
if (notification != null)
void Signal()
{
if (notification.HasValue || notification.ErrorType == BindingErrorType.Error)
var notification = value as BindingNotification;
if (notification != null)
{
Value = notification.Value;
_owner.Changed(this);
if (notification.HasValue || notification.ErrorType == BindingErrorType.Error)
{
Value = notification.Value;
_owner.Changed(this);
}
if (notification.ErrorType != BindingErrorType.None)
{
_owner.Error(this, notification);
}
}
if (notification.ErrorType != BindingErrorType.None)
else
{
_owner.Error(this, notification);
Value = value;
_owner.Changed(this);
}
}
if (Dispatcher.UIThread.CheckAccess())
{
Signal();
}
else
{
Value = value;
_owner.Changed(this);
Dispatcher.UIThread.InvokeAsync(Signal);
}
}
private void Completed()
{
_owner.Completed(this);
if (Dispatcher.UIThread.CheckAccess())
{
_owner.Completed(this);
}
else
{
Dispatcher.UIThread.InvokeAsync(() => _owner.Completed(this));
}
}
}
}

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

@ -154,7 +154,11 @@ namespace Avalonia.Controls.Primitives
if (increaseButton != null)
{
increaseButton.Arrange(new Rect(firstWidth + thumbWidth, 0, remaining - firstWidth, finalSize.Height));
increaseButton.Arrange(new Rect(
firstWidth + thumbWidth,
0,
Math.Max(0, remaining - firstWidth),
finalSize.Height));
}
}
else
@ -185,7 +189,11 @@ namespace Avalonia.Controls.Primitives
if (increaseButton != null)
{
increaseButton.Arrange(new Rect(0, firstHeight + thumbHeight, finalSize.Width, Math.Max(remaining - firstHeight, 0)));
increaseButton.Arrange(new Rect(
0,
firstHeight + thumbHeight,
finalSize.Width,
Math.Max(remaining - firstHeight, 0)));
}
}

28
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Direct.cs

@ -5,10 +5,16 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reactive.Subjects;
using System.Threading;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Data;
using Avalonia.Logging;
using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.Markup.Xaml.Data;
using Avalonia.UnitTests;
using Moq;
using Xunit;
namespace Avalonia.Base.UnitTests
@ -412,6 +418,28 @@ namespace Avalonia.Base.UnitTests
Assert.True(called);
}
[Fact]
public async Task Bind_Executes_On_UIThread()
{
var target = new Class1();
var source = new Subject<object>();
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
var threadingInterfaceMock = new Mock<IPlatformThreadingInterface>();
threadingInterfaceMock.SetupGet(mock => mock.CurrentThreadIsLoopThread)
.Returns(() => Thread.CurrentThread.ManagedThreadId == currentThreadId);
var services = new TestServices(
threadingInterface: threadingInterfaceMock.Object);
using (UnitTestApplication.Start(services))
{
target.Bind(Class1.FooProperty, source);
await Task.Run(() => source.OnNext("foobar"));
}
}
[Fact]
public void AddOwner_Should_Inherit_DefaultBindingMode()
{

26
tests/Avalonia.Controls.UnitTests/Primitives/TrackTests.cs

@ -140,5 +140,31 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Same(thumb.Parent, target);
Assert.Equal(new[] { thumb }, ((ILogical)target).LogicalChildren);
}
[Fact]
public void Should_Not_Pass_Invalid_Arrange_Rect()
{
var thumb = new Thumb { Width = 100.873106060606 };
var increaseButton = new Button { Width = 10 };
var decreaseButton = new Button { Width = 10 };
var target = new Track
{
Height = 12,
Thumb = thumb,
IncreaseButton = increaseButton,
DecreaseButton = decreaseButton,
Orientation = Orientation.Horizontal,
Minimum = 0,
Maximum = 287,
Value = 287,
ViewportSize = 241,
};
target.Measure(Size.Infinity);
// #1297 was occuring here.
target.Arrange(new Rect(0, 0, 221, 12));
}
}
}

Loading…
Cancel
Save