mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-28 23:08:36 +08:00
146 lines
4.0 KiB
C#
146 lines
4.0 KiB
C#
using Avalonia.Input;
|
|
using Avalonia.Headless;
|
|
using AtomUI.Controls.Commons;
|
|
using System.ComponentModel;
|
|
using AtomUI.Controls.Primitives;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Data;
|
|
using Avalonia.Media;
|
|
using Avalonia.Threading;
|
|
using Avalonia.VisualTree;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using AvaloniaWindow = Avalonia.Controls.Window;
|
|
|
|
namespace AtomUI.Desktop.Controls.Tests.Rate;
|
|
|
|
public class RateBindingTests
|
|
{
|
|
static RateBindingTests()
|
|
{
|
|
AvaloniaTestApp.EnsureInitialized();
|
|
}
|
|
|
|
[Fact]
|
|
public void Value_Is_TwoWay_And_DataValidation_Enabled()
|
|
{
|
|
var metadata = Desktop.Controls.Rate.ValueProperty.GetMetadata(typeof(Desktop.Controls.Rate));
|
|
|
|
metadata.DefaultBindingMode.ShouldBe(BindingMode.TwoWay);
|
|
metadata.EnableDataValidation.ShouldBe(true);
|
|
}
|
|
|
|
[Fact]
|
|
public void Value_DefaultBindingMode_Updates_ViewModel()
|
|
{
|
|
var viewModel = new RateBindingViewModel
|
|
{
|
|
Value = 2.0
|
|
};
|
|
var rate = new Desktop.Controls.Rate();
|
|
rate.Bind(
|
|
Desktop.Controls.Rate.ValueProperty,
|
|
new Binding(nameof(RateBindingViewModel.Value))
|
|
{
|
|
Source = viewModel
|
|
});
|
|
|
|
ShowInWindow(rate, () =>
|
|
{
|
|
rate.Value.ShouldBe(2.0);
|
|
|
|
rate.Value = 4.0;
|
|
Dispatcher.UIThread.RunJobs();
|
|
|
|
viewModel.Value.ShouldBe(4.0);
|
|
|
|
var owner = TopLevel.GetTopLevel(rate).ShouldBeOfType<AvaloniaWindow>();
|
|
var star = rate.GetVisualDescendants().OfType<RateItem>().First();
|
|
var point = star.TranslatePoint(new Point(star.Bounds.Width / 2, star.Bounds.Height / 2), owner).ShouldNotBeNull();
|
|
var other = new AvaloniaWindow { Width = 360, Height = 240, Content = new Border { Background = Brushes.Blue } };
|
|
other.Show();
|
|
try
|
|
{
|
|
other.MouseMove(point);
|
|
other.MouseDown(point, MouseButton.Left);
|
|
other.MouseUp(point, MouseButton.Left);
|
|
rate.Value.ShouldBe(4.0);
|
|
viewModel.Value.ShouldBe(4.0, "foreign-window input must not write back a rating");
|
|
|
|
owner.MouseMove(point);
|
|
owner.MouseDown(point, MouseButton.Left);
|
|
owner.MouseUp(point, MouseButton.Left);
|
|
rate.Value.ShouldBe(1.0);
|
|
viewModel.Value.ShouldBe(1.0);
|
|
}
|
|
finally
|
|
{
|
|
other.Close();
|
|
}
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void Template_Frame_Binds_To_BorderThickness()
|
|
{
|
|
var rate = new Desktop.Controls.Rate
|
|
{
|
|
BorderBrush = Brushes.Red,
|
|
BorderThickness = new Thickness(2)
|
|
};
|
|
|
|
ShowInWindow(rate, () =>
|
|
{
|
|
var frame = rate.GetVisualDescendants()
|
|
.OfType<PixelAlignedBorder>()
|
|
.Single(item => item.Name == "Frame");
|
|
|
|
frame.BorderThickness.ShouldBe(new Thickness(2));
|
|
});
|
|
}
|
|
|
|
private static void ShowInWindow(Control content, Action assertion)
|
|
{
|
|
var window = new AvaloniaWindow
|
|
{
|
|
Width = 360,
|
|
Height = 240,
|
|
Content = content
|
|
};
|
|
|
|
try
|
|
{
|
|
window.Show();
|
|
Dispatcher.UIThread.RunJobs();
|
|
assertion();
|
|
}
|
|
finally
|
|
{
|
|
window.Close();
|
|
}
|
|
}
|
|
|
|
private sealed class RateBindingViewModel : INotifyPropertyChanged
|
|
{
|
|
private double _value;
|
|
|
|
public double Value
|
|
{
|
|
get => _value;
|
|
set
|
|
{
|
|
if (Math.Abs(_value - value) < double.Epsilon)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_value = value;
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
|
|
}
|
|
}
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
}
|
|
}
|