Browse Source

Merge branch 'master' into calendar-control

pull/1244/head
Steven Kirk 9 years ago
committed by GitHub
parent
commit
2bc31fce7d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      build/MonoMac.props
  2. 10
      samples/ControlCatalog/Pages/CarouselPage.xaml
  3. 5
      samples/ControlCatalog/Pages/CarouselPage.xaml.cs
  4. 25
      samples/ControlCatalog/Pages/CheckBoxPage.xaml
  5. 2
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  6. 24
      samples/ControlCatalog/Pages/RadioButtonPage.xaml
  7. 2
      src/Avalonia.Controls/Classes.cs
  8. 36
      src/Avalonia.Controls/Primitives/ToggleButton.cs
  9. 9
      src/Avalonia.Controls/RadioButton.cs
  10. 3
      src/Avalonia.Remote.Protocol/BsonStreamTransport.cs
  11. 2
      src/Avalonia.Styling/Styling/Setter.cs
  12. 31
      src/Avalonia.Themes.Default/CheckBox.xaml
  13. 14
      src/Avalonia.Themes.Default/RadioButton.xaml
  14. 25
      src/Avalonia.Visuals/Animation/PageSlide.cs
  15. 10
      tests/Avalonia.Controls.UnitTests/ClassesTests.cs
  16. 57
      tests/Avalonia.Controls.UnitTests/Primitives/ToggleButtonTests.cs
  17. 36
      tests/Avalonia.Controls.UnitTests/RadioButtonTests.cs
  18. 71
      tests/Avalonia.Styling.UnitTests/SetterTests.cs

2
build/MonoMac.props

@ -1,5 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<PackageReference Include="MonoMac.NetStandard" Version="0.0.3" /> <PackageReference Include="MonoMac.NetStandard" Version="0.0.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

10
samples/ControlCatalog/Pages/CarouselPage.xaml

@ -9,7 +9,7 @@
</Button> </Button>
<Carousel Name="carousel"> <Carousel Name="carousel">
<Carousel.Transition> <Carousel.Transition>
<PageSlide Duration="0.25"/> <PageSlide Duration="0.25" Orientation="Vertical" />
</Carousel.Transition> </Carousel.Transition>
<Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"/> <Image Source="resm:ControlCatalog.Assets.delicate-arch-896885_640.jpg"/>
<Image Source="resm:ControlCatalog.Assets.hirsch-899118_640.jpg"/> <Image Source="resm:ControlCatalog.Assets.hirsch-899118_640.jpg"/>
@ -28,6 +28,14 @@
<DropDownItem>Crossfade</DropDownItem> <DropDownItem>Crossfade</DropDownItem>
</DropDown> </DropDown>
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal" Gap="4">
<TextBlock VerticalAlignment="Center">Orientation</TextBlock>
<DropDown Name="orientation" SelectedIndex="1" VerticalAlignment="Center">
<DropDownItem>Horizontal</DropDownItem>
<DropDownItem>Vertical</DropDownItem>
</DropDown>
</StackPanel>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

5
samples/ControlCatalog/Pages/CarouselPage.xaml.cs

@ -11,6 +11,7 @@ namespace ControlCatalog.Pages
private Button _left; private Button _left;
private Button _right; private Button _right;
private DropDown _transition; private DropDown _transition;
private DropDown _orientation;
public CarouselPage() public CarouselPage()
{ {
@ -18,6 +19,7 @@ namespace ControlCatalog.Pages
_left.Click += (s, e) => _carousel.Previous(); _left.Click += (s, e) => _carousel.Previous();
_right.Click += (s, e) => _carousel.Next(); _right.Click += (s, e) => _carousel.Next();
_transition.SelectionChanged += TransitionChanged; _transition.SelectionChanged += TransitionChanged;
_orientation.SelectionChanged += TransitionChanged;
} }
private void InitializeComponent() private void InitializeComponent()
@ -27,6 +29,7 @@ namespace ControlCatalog.Pages
_left = this.FindControl<Button>("left"); _left = this.FindControl<Button>("left");
_right = this.FindControl<Button>("right"); _right = this.FindControl<Button>("right");
_transition = this.FindControl<DropDown>("transition"); _transition = this.FindControl<DropDown>("transition");
_orientation = this.FindControl<DropDown>("orientation");
} }
private void TransitionChanged(object sender, SelectionChangedEventArgs e) private void TransitionChanged(object sender, SelectionChangedEventArgs e)
@ -37,7 +40,7 @@ namespace ControlCatalog.Pages
_carousel.Transition = null; _carousel.Transition = null;
break; break;
case 1: case 1:
_carousel.Transition = new PageSlide(TimeSpan.FromSeconds(0.25)); _carousel.Transition = new PageSlide(TimeSpan.FromSeconds(0.25), _orientation.SelectedIndex == 0 ? PageSlide.SlideAxis.Horizontal : PageSlide.SlideAxis.Vertical);
break; break;
case 2: case 2:
_carousel.Transition = new CrossFade(TimeSpan.FromSeconds(0.25)); _carousel.Transition = new CrossFade(TimeSpan.FromSeconds(0.25));

25
samples/ControlCatalog/Pages/CheckBoxPage.xaml

@ -1,15 +1,28 @@
<UserControl xmlns="https://github.com/avaloniaui"> <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Vertical" Gap="4"> <StackPanel Orientation="Vertical" Gap="4">
<TextBlock Classes="h1">CheckBox</TextBlock> <TextBlock Classes="h1">CheckBox</TextBlock>
<TextBlock Classes="h2">A check box control</TextBlock> <TextBlock Classes="h2">A check box control</TextBlock>
<StackPanel Orientation="Vertical" <StackPanel Orientation="Horizontal"
Margin="0,16,0,0" Margin="0,16,0,0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Gap="16"> Gap="16">
<CheckBox>Unchecked</CheckBox> <StackPanel Orientation="Vertical"
<CheckBox IsChecked="True">Checked</CheckBox> Gap="16">
<CheckBox IsChecked="True" IsEnabled="False">Disabled</CheckBox> <CheckBox>Unchecked</CheckBox>
</StackPanel> <CheckBox IsChecked="True">Checked</CheckBox>
<CheckBox IsChecked="{x:Null}">Indeterminate</CheckBox>
<CheckBox IsChecked="True" IsEnabled="False">Disabled</CheckBox>
</StackPanel>
<StackPanel Orientation="Vertical"
HorizontalAlignment="Center"
Gap="16">
<CheckBox IsChecked="False" IsThreeState="True">Three State: Unchecked</CheckBox>
<CheckBox IsChecked="True" IsThreeState="True">Three State: Checked</CheckBox>
<CheckBox IsChecked="{x:Null}" IsThreeState="True">Three State: Indeterminate</CheckBox>
<CheckBox IsChecked="{x:Null}" IsThreeState="True" IsEnabled="False">Three State: Disabled</CheckBox>
</StackPanel>
</StackPanel>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

2
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@ -36,7 +36,7 @@ namespace ControlCatalog.Pages
}; };
} }
Window GetWindow() => this.FindControl<CheckBox>("IsModal").IsChecked ? (Window)this.VisualRoot : null; Window GetWindow() => this.FindControl<CheckBox>("IsModal").IsChecked.Value ? (Window)this.VisualRoot : null;
private void InitializeComponent() private void InitializeComponent()
{ {

24
samples/ControlCatalog/Pages/RadioButtonPage.xaml

@ -1,15 +1,27 @@
<UserControl xmlns="https://github.com/avaloniaui"> <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Vertical" Gap="4"> <StackPanel Orientation="Vertical" Gap="4">
<TextBlock Classes="h1">RadioButton</TextBlock> <TextBlock Classes="h1">RadioButton</TextBlock>
<TextBlock Classes="h2">Allows the selection of a single option of many</TextBlock> <TextBlock Classes="h2">Allows the selection of a single option of many</TextBlock>
<StackPanel Orientation="Vertical" <StackPanel Orientation="Horizontal"
Margin="0,16,0,0" Margin="0,16,0,0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Gap="16"> Gap="16">
<RadioButton IsChecked="True">Option 1</RadioButton> <StackPanel Orientation="Vertical"
<RadioButton>Option 2</RadioButton> Gap="16">
<RadioButton IsEnabled="False">Disabled</RadioButton> <RadioButton IsChecked="True">Option 1</RadioButton>
</StackPanel> <RadioButton>Option 2</RadioButton>
<RadioButton IsChecked="{x:Null}">Option 3</RadioButton>
<RadioButton IsEnabled="False">Disabled</RadioButton>
</StackPanel>
<StackPanel Orientation="Vertical"
Gap="16">
<RadioButton IsChecked="True" IsThreeState="True">Three States: Option 1</RadioButton>
<RadioButton IsChecked="False" IsThreeState="True">Three States: Option 2</RadioButton>
<RadioButton IsChecked="{x:Null}" IsThreeState="True">Three States: Option 3</RadioButton>
<RadioButton IsChecked="{x:Null}" IsThreeState="True" IsEnabled="False">Disabled</RadioButton>
</StackPanel>
</StackPanel>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

2
src/Avalonia.Controls/Classes.cs

@ -179,7 +179,7 @@ namespace Avalonia.Controls
{ {
ThrowIfPseudoclass(name, "removed"); ThrowIfPseudoclass(name, "removed");
if (!Contains(name)) if (Contains(name))
{ {
c.Add(name); c.Add(name);
} }

36
src/Avalonia.Controls/Primitives/ToggleButton.cs

@ -9,26 +9,37 @@ namespace Avalonia.Controls.Primitives
{ {
public class ToggleButton : Button public class ToggleButton : Button
{ {
public static readonly DirectProperty<ToggleButton, bool> IsCheckedProperty = public static readonly DirectProperty<ToggleButton, bool?> IsCheckedProperty =
AvaloniaProperty.RegisterDirect<ToggleButton, bool>( AvaloniaProperty.RegisterDirect<ToggleButton, bool?>(
"IsChecked", nameof(IsChecked),
o => o.IsChecked, o => o.IsChecked,
(o,v) => o.IsChecked = v, (o, v) => o.IsChecked = v,
defaultBindingMode: BindingMode.TwoWay); defaultBindingMode: BindingMode.TwoWay);
private bool _isChecked; public static readonly StyledProperty<bool> IsThreeStateProperty =
AvaloniaProperty.Register<ToggleButton, bool>(nameof(IsThreeState));
private bool? _isChecked = false;
static ToggleButton() static ToggleButton()
{ {
PseudoClass(IsCheckedProperty, ":checked"); PseudoClass(IsCheckedProperty, c => c == true, ":checked");
PseudoClass(IsCheckedProperty, c => c == false, ":unchecked");
PseudoClass(IsCheckedProperty, c => c == null, ":indeterminate");
} }
public bool IsChecked public bool? IsChecked
{ {
get { return _isChecked; } get { return _isChecked; }
set { SetAndRaise(IsCheckedProperty, ref _isChecked, value); } set { SetAndRaise(IsCheckedProperty, ref _isChecked, value); }
} }
public bool IsThreeState
{
get => GetValue(IsThreeStateProperty);
set => SetValue(IsThreeStateProperty, value);
}
protected override void OnClick() protected override void OnClick()
{ {
Toggle(); Toggle();
@ -37,7 +48,16 @@ namespace Avalonia.Controls.Primitives
protected virtual void Toggle() protected virtual void Toggle()
{ {
IsChecked = !IsChecked; if (IsChecked.HasValue)
if (IsChecked.Value)
if (IsThreeState)
IsChecked = null;
else
IsChecked = false;
else
IsChecked = true;
else
IsChecked = false;
} }
} }
} }

9
src/Avalonia.Controls/RadioButton.cs

@ -17,17 +17,17 @@ namespace Avalonia.Controls
protected override void Toggle() protected override void Toggle()
{ {
if (!IsChecked) if (!IsChecked.GetValueOrDefault())
{ {
IsChecked = true; IsChecked = true;
} }
} }
private void IsCheckedChanged(bool value) private void IsCheckedChanged(bool? value)
{ {
var parent = this.GetVisualParent(); var parent = this.GetVisualParent();
if (value && parent != null) if (value.GetValueOrDefault() && parent != null)
{ {
var siblings = parent var siblings = parent
.GetVisualChildren() .GetVisualChildren()
@ -36,7 +36,8 @@ namespace Avalonia.Controls
foreach (var sibling in siblings) foreach (var sibling in siblings)
{ {
sibling.IsChecked = false; if (sibling.IsChecked.GetValueOrDefault())
sibling.IsChecked = false;
} }
} }
} }

3
src/Avalonia.Remote.Protocol/BsonStreamTransport.cs

@ -64,7 +64,6 @@ namespace Avalonia.Remote.Protocol
async Task Reader() async Task Reader()
{ {
Task.Yield();
try try
{ {
while (true) while (true)
@ -147,4 +146,4 @@ namespace Avalonia.Remote.Protocol
public event Action<IAvaloniaRemoteTransportConnection, object> OnMessage; public event Action<IAvaloniaRemoteTransportConnection, object> OnMessage;
public event Action<IAvaloniaRemoteTransportConnection, Exception> OnException; public event Action<IAvaloniaRemoteTransportConnection, Exception> OnException;
} }
} }

2
src/Avalonia.Styling/Styling/Setter.cs

@ -174,7 +174,7 @@ namespace Avalonia.Styling
} }
else else
{ {
return sourceInstance.WithPriority(BindingPriority.StyleTrigger); return sourceInstance.WithPriority(BindingPriority.Style);
} }
} }
} }

31
src/Avalonia.Themes.Default/CheckBox.xaml

@ -12,14 +12,23 @@
Width="18" Width="18"
Height="18" Height="18"
VerticalAlignment="Center"> VerticalAlignment="Center">
<Path Name="checkMark" <Panel>
Fill="{DynamicResource HighlightBrush}" <Path Name="checkMark"
Width="11" Fill="{DynamicResource HighlightBrush}"
Height="10" Width="11"
Stretch="Uniform" Height="10"
HorizontalAlignment="Center" Stretch="Uniform"
VerticalAlignment="Center" HorizontalAlignment="Center"
Data="M 1145.607177734375,430 C1145.607177734375,430 1141.449951171875,435.0772705078125 1141.449951171875,435.0772705078125 1141.449951171875,435.0772705078125 1139.232177734375,433.0999755859375 1139.232177734375,433.0999755859375 1139.232177734375,433.0999755859375 1138,434.5538330078125 1138,434.5538330078125 1138,434.5538330078125 1141.482177734375,438 1141.482177734375,438 1141.482177734375,438 1141.96875,437.9375 1141.96875,437.9375 1141.96875,437.9375 1147,431.34619140625 1147,431.34619140625 1147,431.34619140625 1145.607177734375,430 1145.607177734375,430 z"/> VerticalAlignment="Center"
Data="M 1145.607177734375,430 C1145.607177734375,430 1141.449951171875,435.0772705078125 1141.449951171875,435.0772705078125 1141.449951171875,435.0772705078125 1139.232177734375,433.0999755859375 1139.232177734375,433.0999755859375 1139.232177734375,433.0999755859375 1138,434.5538330078125 1138,434.5538330078125 1138,434.5538330078125 1141.482177734375,438 1141.482177734375,438 1141.482177734375,438 1141.96875,437.9375 1141.96875,437.9375 1141.96875,437.9375 1147,431.34619140625 1147,431.34619140625 1147,431.34619140625 1145.607177734375,430 1145.607177734375,430 z"/>
<Rectangle Name="indeterminateMark"
Fill="{DynamicResource HighlightBrush}"
Width="10"
Height="10"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Panel>
</Border> </Border>
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
@ -37,9 +46,15 @@
<Style Selector="CheckBox /template/ Path#checkMark"> <Style Selector="CheckBox /template/ Path#checkMark">
<Setter Property="IsVisible" Value="False"/> <Setter Property="IsVisible" Value="False"/>
</Style> </Style>
<Style Selector="CheckBox /template/ Rectangle#indeterminateMark">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="CheckBox:checked /template/ Path#checkMark"> <Style Selector="CheckBox:checked /template/ Path#checkMark">
<Setter Property="IsVisible" Value="True"/> <Setter Property="IsVisible" Value="True"/>
</Style> </Style>
<Style Selector="CheckBox:indeterminate /template/ Rectangle#indeterminateMark">
<Setter Property="IsVisible" Value="True"/>
</Style>
<Style Selector="CheckBox:disabled /template/ Border#border"> <Style Selector="CheckBox:disabled /template/ Border#border">
<Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/> <Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/>
</Style> </Style>

14
src/Avalonia.Themes.Default/RadioButton.xaml

@ -20,6 +20,14 @@
UseLayoutRounding="False" UseLayoutRounding="False"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center"/> VerticalAlignment="Center"/>
<Ellipse Name="indeterminateMark"
Fill="{DynamicResource ThemeAccentBrush}"
Width="10"
Height="10"
Stretch="Uniform"
UseLayoutRounding="False"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
@ -36,9 +44,15 @@
<Style Selector="RadioButton /template/ Ellipse#checkMark"> <Style Selector="RadioButton /template/ Ellipse#checkMark">
<Setter Property="IsVisible" Value="False"/> <Setter Property="IsVisible" Value="False"/>
</Style> </Style>
<Style Selector="RadioButton /template/ Ellipse#indeterminateMark">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="RadioButton:checked /template/ Ellipse#checkMark"> <Style Selector="RadioButton:checked /template/ Ellipse#checkMark">
<Setter Property="IsVisible" Value="True"/> <Setter Property="IsVisible" Value="True"/>
</Style> </Style>
<Style Selector="RadioButton:indeterminate /template/ Ellipse#indeterminateMark">
<Setter Property="IsVisible" Value="True"/>
</Style>
<Style Selector="RadioButton:disabled /template/ Ellipse#border"> <Style Selector="RadioButton:disabled /template/ Ellipse#border">
<Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/> <Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}"/>
</Style> </Style>

25
src/Avalonia.Visuals/Animation/PageSlide.cs

@ -15,6 +15,15 @@ namespace Avalonia.Animation
/// </summary> /// </summary>
public class PageSlide : IPageTransition public class PageSlide : IPageTransition
{ {
/// <summary>
/// The axis on which the PageSlide should occur
/// </summary>
public enum SlideAxis
{
Horizontal,
Vertical
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PageSlide"/> class. /// Initializes a new instance of the <see cref="PageSlide"/> class.
/// </summary> /// </summary>
@ -26,9 +35,11 @@ namespace Avalonia.Animation
/// Initializes a new instance of the <see cref="PageSlide"/> class. /// Initializes a new instance of the <see cref="PageSlide"/> class.
/// </summary> /// </summary>
/// <param name="duration">The duration of the animation.</param> /// <param name="duration">The duration of the animation.</param>
public PageSlide(TimeSpan duration) /// <param name="orientation">The axis on which the animation should occur</param>
public PageSlide(TimeSpan duration, SlideAxis orientation = SlideAxis.Horizontal)
{ {
Duration = duration; Duration = duration;
Orientation = orientation;
} }
/// <summary> /// <summary>
@ -36,6 +47,11 @@ namespace Avalonia.Animation
/// </summary> /// </summary>
public TimeSpan Duration { get; set; } public TimeSpan Duration { get; set; }
/// <summary>
/// Gets the duration of the animation.
/// </summary>
public SlideAxis Orientation { get; set; }
/// <summary> /// <summary>
/// Starts the animation. /// Starts the animation.
/// </summary> /// </summary>
@ -55,7 +71,8 @@ namespace Avalonia.Animation
{ {
var tasks = new List<Task>(); var tasks = new List<Task>();
var parent = GetVisualParent(from, to); var parent = GetVisualParent(from, to);
var distance = parent.Bounds.Width; var distance = Orientation == SlideAxis.Horizontal ? parent.Bounds.Width : parent.Bounds.Height;
var translateProperty = Orientation == SlideAxis.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty;
if (from != null) if (from != null)
{ {
@ -63,7 +80,7 @@ namespace Avalonia.Animation
from.RenderTransform = transform; from.RenderTransform = transform;
tasks.Add(Animate.Property( tasks.Add(Animate.Property(
transform, transform,
TranslateTransform.XProperty, translateProperty,
0.0, 0.0,
forward ? -distance : distance, forward ? -distance : distance,
LinearEasing.For<double>(), LinearEasing.For<double>(),
@ -77,7 +94,7 @@ namespace Avalonia.Animation
to.IsVisible = true; to.IsVisible = true;
tasks.Add(Animate.Property( tasks.Add(Animate.Property(
transform, transform,
TranslateTransform.XProperty, translateProperty,
forward ? distance : -distance, forward ? distance : -distance,
0.0, 0.0,
LinearEasing.For<double>(), LinearEasing.For<double>(),

10
tests/Avalonia.Controls.UnitTests/ClassesTests.cs

@ -161,5 +161,15 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new[] { ":baz" }, target); Assert.Equal(new[] { ":baz" }, target);
} }
[Fact]
public void RemoveAll_Should_Remove_Classes()
{
var target = new Classes("foo", "bar", "baz");
target.RemoveAll(new[] { "bar", "baz" });
Assert.Equal(new[] { "foo" }, target);
}
} }
} }

57
tests/Avalonia.Controls.UnitTests/Primitives/ToggleButtonTests.cs

@ -0,0 +1,57 @@
using Avalonia.Markup.Xaml.Data;
using Avalonia.UnitTests;
using Xunit;
namespace Avalonia.Controls.Primitives.UnitTests
{
public class ToggleButtonTests
{
private const string uncheckedClass = ":unchecked";
private const string checkedClass = ":checked";
private const string indeterminateClass = ":indeterminate";
[Theory]
[InlineData(false, uncheckedClass, false)]
[InlineData(false, uncheckedClass, true)]
[InlineData(true, checkedClass, false)]
[InlineData(true, checkedClass, true)]
[InlineData(null, indeterminateClass, false)]
[InlineData(null, indeterminateClass, true)]
public void ToggleButton_Has_Correct_Class_According_To_Is_Checked(bool? isChecked, string expectedClass, bool isThreeState)
{
var toggleButton = new ToggleButton();
toggleButton.IsThreeState = isThreeState;
toggleButton.IsChecked = isChecked;
Assert.Contains(expectedClass, toggleButton.Classes);
}
[Fact]
public void ToggleButton_Is_Checked_Binds_To_Bool()
{
var toggleButton = new ToggleButton();
var source = new Class1();
toggleButton.DataContext = source;
toggleButton.Bind(ToggleButton.IsCheckedProperty, new Binding("Foo"));
source.Foo = true;
Assert.True(toggleButton.IsChecked);
source.Foo = false;
Assert.False(toggleButton.IsChecked);
}
private class Class1 : NotifyingBase
{
private bool _foo;
public bool Foo
{
get { return _foo; }
set { _foo = value; RaisePropertyChanged(); }
}
}
}
}

36
tests/Avalonia.Controls.UnitTests/RadioButtonTests.cs

@ -0,0 +1,36 @@
using Avalonia.Markup.Xaml.Data;
using Avalonia.UnitTests;
using Xunit;
namespace Avalonia.Controls.UnitTests
{
public class RadioButtonTests
{
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Indeterminate_RadioButton_Is_Not_Unchecked_After_Checking_Other_Radio_Button(bool isThreeState)
{
var panel = new Panel();
var radioButton1 = new RadioButton();
radioButton1.IsThreeState = false;
radioButton1.IsChecked = false;
var radioButton2 = new RadioButton();
radioButton2.IsThreeState = isThreeState;
radioButton2.IsChecked = null;
panel.Children.Add(radioButton1);
panel.Children.Add(radioButton2);
Assert.Null(radioButton2.IsChecked);
radioButton1.IsChecked = true;
Assert.True(radioButton1.IsChecked);
Assert.Null(radioButton2.IsChecked);
}
}
}

71
tests/Avalonia.Styling.UnitTests/SetterTests.cs

@ -86,6 +86,77 @@ namespace Avalonia.Styling.UnitTests
Assert.Null(control.Tag); Assert.Null(control.Tag);
} }
[Fact]
public void Setter_Should_Apply_Value_Without_Activator_With_Style_Priority()
{
var control = new Mock<IStyleable>();
var style = Mock.Of<Style>();
var setter = new Setter(TextBlock.TextProperty, "foo");
setter.Apply(style, control.Object, null);
control.Verify(x => x.Bind(
TextBlock.TextProperty,
It.IsAny<IObservable<object>>(),
BindingPriority.Style));
}
[Fact]
public void Setter_Should_Apply_Value_With_Activator_With_StyleTrigger_Priority()
{
var control = new Mock<IStyleable>();
var style = Mock.Of<Style>();
var setter = new Setter(TextBlock.TextProperty, "foo");
var activator = new Subject<bool>();
setter.Apply(style, control.Object, activator);
control.Verify(x => x.Bind(
TextBlock.TextProperty,
It.IsAny<IObservable<object>>(),
BindingPriority.StyleTrigger));
}
[Fact]
public void Setter_Should_Apply_Binding_Without_Activator_With_Style_Priority()
{
var control = new Mock<IStyleable>();
var style = Mock.Of<Style>();
var setter = new Setter(TextBlock.TextProperty, CreateMockBinding(TextBlock.TextProperty));
setter.Apply(style, control.Object, null);
control.Verify(x => x.Bind(
TextBlock.TextProperty,
It.IsAny<IObservable<object>>(),
BindingPriority.Style));
}
[Fact]
public void Setter_Should_Apply_Binding_With_Activator_With_StyleTrigger_Priority()
{
var control = new Mock<IStyleable>();
var style = Mock.Of<Style>();
var setter = new Setter(TextBlock.TextProperty, CreateMockBinding(TextBlock.TextProperty));
var activator = new Subject<bool>();
setter.Apply(style, control.Object, activator);
control.Verify(x => x.Bind(
TextBlock.TextProperty,
It.IsAny<IObservable<object>>(),
BindingPriority.StyleTrigger));
}
private IBinding CreateMockBinding(AvaloniaProperty property)
{
var subject = new Subject<object>();
var descriptor = InstancedBinding.OneWay(subject);
var binding = Mock.Of<IBinding>(x =>
x.Initiate(It.IsAny<IAvaloniaObject>(), property, null, false) == descriptor);
return binding;
}
private class TestConverter : IValueConverter private class TestConverter : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

Loading…
Cancel
Save