Browse Source

Merge remote-tracking branch 'origin/master' into fixes/dialog-main-window-activation

pull/5399/head
Dan Walmsley 6 years ago
parent
commit
96d92e0dea
  1. 4
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 2
      .github/ISSUE_TEMPLATE/feature_request.md
  3. 4
      .ncrunch/Avalonia.MicroCom.v3.ncrunchproject
  4. 3
      .ncrunch/Avalonia.Win32.v3.ncrunchproject
  5. 1
      .ncrunch/Direct3DInteropSample.v3.ncrunchproject
  6. 2
      readme.md
  7. 22
      src/Avalonia.Base/Data/IndexerBinding.cs
  8. 6
      src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs
  9. 3
      src/Avalonia.Controls/Primitives/VisualLayerManager.cs
  10. 111
      src/Avalonia.Controls/Slider.cs
  11. 13
      src/Avalonia.Controls/ToolTipService.cs
  12. 2
      src/Avalonia.OpenGL/GlInterface.cs
  13. 1
      src/Avalonia.Themes.Default/MenuItem.xaml
  14. 1
      src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml
  15. 3
      src/Avalonia.Themes.Fluent/Controls/Expander.xaml
  16. 1
      src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml
  17. 1
      src/Avalonia.Themes.Fluent/Controls/RadioButton.xaml
  18. 2
      src/Avalonia.X11/X11Atoms.cs
  19. 4
      src/Avalonia.X11/X11Screens.cs
  20. 28
      tests/Avalonia.Controls.UnitTests/ToolTipTests.cs
  21. 7
      tests/Avalonia.Markup.Xaml.UnitTests/Converters/PointsListTypeConverterTests.cs

4
.github/ISSUE_TEMPLATE/bug_report.md

@ -1,8 +1,8 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve Avalonia
title: '' title: ''
labels: '' labels: bug
assignees: '' assignees: ''
--- ---

2
.github/ISSUE_TEMPLATE/feature_request.md

@ -2,7 +2,7 @@
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: '' title: ''
labels: '' labels: enhancement
assignees: '' assignees: ''
--- ---

4
.ncrunch/Avalonia.MicroCom.v3.ncrunchproject

@ -1,5 +1,3 @@
<ProjectConfiguration> <ProjectConfiguration>
<Settings> <Settings />
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration> </ProjectConfiguration>

3
.ncrunch/Avalonia.Win32.v3.ncrunchproject

@ -1,5 +1,8 @@
<ProjectConfiguration> <ProjectConfiguration>
<Settings> <Settings>
<AdditionalFilesToIncludeForProject>
<Value>..\..\tools\MicroComGenerator\bin\Debug\netcoreapp3.1\**.*</Value>
</AdditionalFilesToIncludeForProject>
<HiddenComponentWarnings> <HiddenComponentWarnings>
<Value>MissingOrIgnoredProjectReference</Value> <Value>MissingOrIgnoredProjectReference</Value>
</HiddenComponentWarnings> </HiddenComponentWarnings>

1
.ncrunch/Direct3DInteropSample.v3.ncrunchproject

@ -3,6 +3,7 @@
<HiddenComponentWarnings> <HiddenComponentWarnings>
<Value>MissingOrIgnoredProjectReference</Value> <Value>MissingOrIgnoredProjectReference</Value>
</HiddenComponentWarnings> </HiddenComponentWarnings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings> </Settings>
</ProjectConfiguration> </ProjectConfiguration>

2
readme.md

@ -12,8 +12,6 @@ Avalonia is a cross-platform XAML-based UI framework providing a flexible stylin
([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery)) ([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
> **Note:** The UI theme you see in the picture above is still work-in-progress and will be available in the upcoming Avalonia 0.10.0 release. However, you can connect to our nightly build feed and install latest pre-release versions of Avalonia NuGet packages, if you are willing to help out with the development and testing. See [Using nightly build feed](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) for more info.
To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been. [Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia! To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been. [Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia!
## 🚀 Getting Started ## 🚀 Getting Started

22
src/Avalonia.Base/Data/IndexerBinding.cs

@ -1,6 +1,4 @@
using System; namespace Avalonia.Data
namespace Avalonia.Data
{ {
public class IndexerBinding : IBinding public class IndexerBinding : IBinding
{ {
@ -24,23 +22,7 @@ namespace Avalonia.Data
object anchor = null, object anchor = null,
bool enableDataValidation = false) bool enableDataValidation = false)
{ {
var mode = Mode == BindingMode.Default ? return new InstancedBinding(Source.GetSubject(Property), Mode, BindingPriority.LocalValue);
targetProperty.GetMetadata(target.GetType()).DefaultBindingMode :
Mode;
switch (mode)
{
case BindingMode.OneTime:
return InstancedBinding.OneTime(Source.GetObservable(Property));
case BindingMode.OneWay:
return InstancedBinding.OneWay(Source.GetObservable(Property));
case BindingMode.OneWayToSource:
return InstancedBinding.OneWayToSource(Source.GetSubject(Property));
case BindingMode.TwoWay:
return InstancedBinding.TwoWay(Source.GetSubject(Property));
default:
throw new NotSupportedException("Unsupported BindingMode.");
}
} }
} }
} }

6
src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs

@ -2,6 +2,7 @@ using System;
using System.Linq; using System.Linq;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Rendering; using Avalonia.Rendering;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.VisualTree; using Avalonia.VisualTree;
@ -17,6 +18,11 @@ namespace Avalonia.Controls.Primitives
{ {
public IInputElement? InputPassThroughElement { get; set; } public IInputElement? InputPassThroughElement { get; set; }
static LightDismissOverlayLayer()
{
BackgroundProperty.OverrideDefaultValue<LightDismissOverlayLayer>(Brushes.Transparent);
}
/// <summary> /// <summary>
/// Returns the light dismiss overlay for a specified visual. /// Returns the light dismiss overlay for a specified visual.
/// </summary> /// </summary>

3
src/Avalonia.Controls/Primitives/VisualLayerManager.cs

@ -67,14 +67,11 @@ namespace Avalonia.Controls.Primitives
{ {
get get
{ {
if (IsPopup)
return null;
var rv = FindLayer<LightDismissOverlayLayer>(); var rv = FindLayer<LightDismissOverlayLayer>();
if (rv == null) if (rv == null)
{ {
rv = new LightDismissOverlayLayer rv = new LightDismissOverlayLayer
{ {
Background = Brushes.Transparent,
IsVisible = false IsVisible = false
}; };

111
src/Avalonia.Controls/Slider.cs

@ -11,7 +11,6 @@ using Avalonia.Utilities;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
/// <summary> /// <summary>
/// Enum which describes how to position the ticks in a <see cref="Slider"/>. /// Enum which describes how to position the ticks in a <see cref="Slider"/>.
/// </summary> /// </summary>
@ -84,6 +83,9 @@ namespace Avalonia.Controls
private IDisposable _increaseButtonSubscription; private IDisposable _increaseButtonSubscription;
private IDisposable _increaseButtonReleaseDispose; private IDisposable _increaseButtonReleaseDispose;
private IDisposable _pointerMovedDispose; private IDisposable _pointerMovedDispose;
private IDisposable _trackOnKeyDownDispose;
private const double Tolerance = 0.0001;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="Slider"/> class. /// Initializes static members of the <see cref="Slider"/> class.
@ -95,7 +97,7 @@ namespace Avalonia.Controls
Thumb.DragStartedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble); Thumb.DragStartedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragCompleted(e), Thumb.DragCompletedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragCompleted(e),
RoutingStrategies.Bubble); RoutingStrategies.Bubble);
ValueProperty.OverrideMetadata<Slider>(new DirectPropertyMetadata<double>(enableDataValidation: true)); ValueProperty.OverrideMetadata<Slider>(new DirectPropertyMetadata<double>(enableDataValidation: true));
} }
@ -157,13 +159,14 @@ namespace Avalonia.Controls
protected override void OnApplyTemplate(TemplateAppliedEventArgs e) protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
base.OnApplyTemplate(e); base.OnApplyTemplate(e);
_decreaseButtonPressDispose?.Dispose(); _decreaseButtonPressDispose?.Dispose();
_decreaseButtonReleaseDispose?.Dispose(); _decreaseButtonReleaseDispose?.Dispose();
_increaseButtonSubscription?.Dispose(); _increaseButtonSubscription?.Dispose();
_increaseButtonReleaseDispose?.Dispose(); _increaseButtonReleaseDispose?.Dispose();
_pointerMovedDispose?.Dispose(); _pointerMovedDispose?.Dispose();
_trackOnKeyDownDispose?.Dispose();
_decreaseButton = e.NameScope.Find<Button>("PART_DecreaseButton"); _decreaseButton = e.NameScope.Find<Button>("PART_DecreaseButton");
_track = e.NameScope.Find<Track>("PART_Track"); _track = e.NameScope.Find<Track>("PART_Track");
_increaseButton = e.NameScope.Find<Button>("PART_IncreaseButton"); _increaseButton = e.NameScope.Find<Button>("PART_IncreaseButton");
@ -171,6 +174,7 @@ namespace Avalonia.Controls
if (_track != null) if (_track != null)
{ {
_track.IsThumbDragHandled = true; _track.IsThumbDragHandled = true;
_trackOnKeyDownDispose = _track.AddDisposableHandler(KeyDownEvent, TrackOnKeyDown);
} }
if (_decreaseButton != null) if (_decreaseButton != null)
@ -188,6 +192,94 @@ namespace Avalonia.Controls
_pointerMovedDispose = this.AddDisposableHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel); _pointerMovedDispose = this.AddDisposableHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel);
} }
private void TrackOnKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyModifiers != KeyModifiers.None) return;
switch (e.Key)
{
case Key.Left:
MoveToNextTick(-SmallChange);
break;
case Key.Right:
MoveToNextTick(SmallChange);
break;
case Key.PageUp:
MoveToNextTick(-LargeChange);
break;
case Key.PageDown:
MoveToNextTick(LargeChange);
break;
case Key.Home:
Value = Minimum;
break;
case Key.End:
Value = Maximum;
break;
}
}
private void MoveToNextTick(double direction)
{
if (direction == 0.0) return;
var value = Value;
// Find the next value by snapping
var next = SnapToTick(Math.Max(Minimum, Math.Min(Maximum, value + direction)));
var greaterThan = direction > 0; //search for the next tick greater than value?
// If the snapping brought us back to value, find the next tick point
if (Math.Abs(next - value) < Tolerance
&& !(greaterThan && Math.Abs(value - Maximum) < Tolerance) // Stop if searching up if already at Max
&& !(!greaterThan && Math.Abs(value - Minimum) < Tolerance)) // Stop if searching down if already at Min
{
var ticks = Ticks;
// If ticks collection is available, use it.
// Note that ticks may be unsorted.
if (ticks != null && ticks.Count > 0)
{
foreach (var tick in ticks)
{
// Find the smallest tick greater than value or the largest tick less than value
if (greaterThan && MathUtilities.GreaterThan(tick, value) &&
(MathUtilities.LessThan(tick, next) || Math.Abs(next - value) < Tolerance)
|| !greaterThan && MathUtilities.LessThan(tick, value) &&
(MathUtilities.GreaterThan(tick, next) || Math.Abs(next - value) < Tolerance))
{
next = tick;
}
}
}
else if (MathUtilities.GreaterThan(TickFrequency, 0.0))
{
// Find the current tick we are at
var tickNumber = Math.Round((value - Minimum) / TickFrequency);
if (greaterThan)
tickNumber += 1.0;
else
tickNumber -= 1.0;
next = Minimum + tickNumber * TickFrequency;
}
}
// Update if we've found a better value
if (Math.Abs(next - value) > Tolerance)
{
Value = next;
}
}
private void TrackMoved(object sender, PointerEventArgs e) private void TrackMoved(object sender, PointerEventArgs e)
{ {
if (_isDragging) if (_isDragging)
@ -272,19 +364,18 @@ namespace Avalonia.Controls
{ {
if (IsSnapToTickEnabled) if (IsSnapToTickEnabled)
{ {
double previous = Minimum; var previous = Minimum;
double next = Maximum; var next = Maximum;
// This property is rarely set so let's try to avoid the GetValue // This property is rarely set so let's try to avoid the GetValue
var ticks = Ticks; var ticks = Ticks;
// If ticks collection is available, use it. // If ticks collection is available, use it.
// Note that ticks may be unsorted. // Note that ticks may be unsorted.
if ((ticks != null) && (ticks.Count > 0)) if (ticks != null && ticks.Count > 0)
{ {
for (int i = 0; i < ticks.Count; i++) foreach (var tick in ticks)
{ {
double tick = ticks[i];
if (MathUtilities.AreClose(tick, value)) if (MathUtilities.AreClose(tick, value))
{ {
return value; return value;
@ -302,7 +393,7 @@ namespace Avalonia.Controls
} }
else if (MathUtilities.GreaterThan(TickFrequency, 0.0)) else if (MathUtilities.GreaterThan(TickFrequency, 0.0))
{ {
previous = Minimum + (Math.Round(((value - Minimum) / TickFrequency)) * TickFrequency); previous = Minimum + Math.Round((value - Minimum) / TickFrequency) * TickFrequency;
next = Math.Min(Maximum, previous + TickFrequency); next = Math.Min(Maximum, previous + TickFrequency);
} }

13
src/Avalonia.Controls/ToolTipService.cs

@ -38,9 +38,16 @@ namespace Avalonia.Controls
if (ToolTip.GetIsOpen(control) && e.NewValue != e.OldValue && !(e.NewValue is ToolTip)) if (ToolTip.GetIsOpen(control) && e.NewValue != e.OldValue && !(e.NewValue is ToolTip))
{ {
var tip = control.GetValue(ToolTip.ToolTipProperty); if (e.NewValue is null)
{
tip.Content = e.NewValue; Close(control);
}
else
{
var tip = control.GetValue(ToolTip.ToolTipProperty);
tip.Content = e.NewValue;
}
} }
} }

2
src/Avalonia.OpenGL/GlInterface.cs

@ -128,7 +128,7 @@ namespace Avalonia.OpenGL
int dstY1, int dstY1,
int mask, int mask,
int filter); int filter);
[GlMinVersionEntryPoint("glBlitFramebuffer", 3, 0)] [GlMinVersionEntryPoint("glBlitFramebuffer", 3, 0), GlOptionalEntryPoint]
public GlBlitFramebuffer BlitFramebuffer { get; } public GlBlitFramebuffer BlitFramebuffer { get; }
public delegate void GlGenRenderbuffers(int count, int[] res); public delegate void GlGenRenderbuffers(int count, int[] res);

1
src/Avalonia.Themes.Default/MenuItem.xaml

@ -60,6 +60,7 @@
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
PlacementMode="Right" PlacementMode="Right"
IsLightDismissEnabled="True" IsLightDismissEnabled="True"
OverlayInputPassThroughElement="{Binding $parent[MenuItem]}"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}"> IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource ThemeBorderMidBrush}" BorderBrush="{DynamicResource ThemeBorderMidBrush}"

1
src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml

@ -11,7 +11,6 @@
<Setter Property="HorizontalContentAlignment" Value="Left" /> <Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="32" /> <Setter Property="MinHeight" Value="32" />
<!--<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" /> <!--<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />--> <Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />-->

3
src/Avalonia.Themes.Fluent/Controls/Expander.xaml

@ -26,6 +26,9 @@
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</Style> </Style>
<Style Selector="Expander[IsExpanded=true] /template/ ToggleButton#PART_toggle /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="TextBlock.Foreground" Value="{DynamicResource ToggleButtonForeground}"/>
</Style>
<Style Selector="Expander[ExpandDirection=Up]"> <Style Selector="Expander[ExpandDirection=Up]">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>

1
src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

@ -112,6 +112,7 @@
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
WindowManagerAddShadowHint="False" WindowManagerAddShadowHint="False"
PlacementMode="Right" PlacementMode="Right"
OverlayInputPassThroughElement="{Binding $parent[MenuItem]}"
HorizontalOffset="{DynamicResource MenuFlyoutSubItemPopupHorizontalOffset}" HorizontalOffset="{DynamicResource MenuFlyoutSubItemPopupHorizontalOffset}"
IsLightDismissEnabled="True" IsLightDismissEnabled="True"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}"> IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">

1
src/Avalonia.Themes.Fluent/Controls/RadioButton.xaml

@ -19,7 +19,6 @@
<Setter Property="HorizontalContentAlignment" Value="Left" /> <Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="RadioButton"> <ControlTemplate TargetType="RadioButton">
<Border Name="RootBorder" <Border Name="RootBorder"

2
src/Avalonia.X11/X11Atoms.cs

@ -114,7 +114,7 @@ namespace Avalonia.X11
public readonly IntPtr XA_WM_CLASS = (IntPtr)67; public readonly IntPtr XA_WM_CLASS = (IntPtr)67;
public readonly IntPtr XA_WM_TRANSIENT_FOR = (IntPtr)68; public readonly IntPtr XA_WM_TRANSIENT_FOR = (IntPtr)68;
public readonly IntPtr RR_PROPERTY_RANDR_EDID = (IntPtr)82; public readonly IntPtr EDID;
public readonly IntPtr WM_PROTOCOLS; public readonly IntPtr WM_PROTOCOLS;
public readonly IntPtr WM_DELETE_WINDOW; public readonly IntPtr WM_DELETE_WINDOW;

4
src/Avalonia.X11/X11Screens.cs

@ -91,12 +91,12 @@ namespace Avalonia.X11
var hasEDID = false; var hasEDID = false;
for(var pc = 0; pc < propertyCount; pc++) for(var pc = 0; pc < propertyCount; pc++)
{ {
if(properties[pc] == _x11.Atoms.RR_PROPERTY_RANDR_EDID) if(properties[pc] == _x11.Atoms.EDID)
hasEDID = true; hasEDID = true;
} }
if(!hasEDID) if(!hasEDID)
return null; return null;
XRRGetOutputProperty(_x11.Display, rrOutput, _x11.Atoms.RR_PROPERTY_RANDR_EDID, 0, EDIDStructureLength, false, false, _x11.Atoms.AnyPropertyType, out IntPtr actualType, out int actualFormat, out int bytesAfter, out _, out IntPtr prop); XRRGetOutputProperty(_x11.Display, rrOutput, _x11.Atoms.EDID, 0, EDIDStructureLength, false, false, _x11.Atoms.AnyPropertyType, out IntPtr actualType, out int actualFormat, out int bytesAfter, out _, out IntPtr prop);
if(actualType != _x11.Atoms.XA_INTEGER) if(actualType != _x11.Atoms.XA_INTEGER)
return null; return null;
if(actualFormat != 8) // Expecting an byte array if(actualFormat != 8) // Expecting an byte array

28
tests/Avalonia.Controls.UnitTests/ToolTipTests.cs

@ -270,6 +270,34 @@ namespace Avalonia.Controls.UnitTests
Assert.Empty(toolTip.Classes); Assert.Empty(toolTip.Classes);
} }
} }
[Fact]
public void Should_Close_On_Null_Tip()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var window = new Window();
var target = new Decorator()
{
[ToolTip.TipProperty] = "Tip",
[ToolTip.ShowDelayProperty] = 0
};
window.Content = target;
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
_mouseHelper.Enter(target);
Assert.True(ToolTip.GetIsOpen(target));
target[ToolTip.TipProperty] = null;
Assert.False(ToolTip.GetIsOpen(target));
}
}
} }
internal class ToolTipViewModel internal class ToolTipViewModel

7
tests/Avalonia.Markup.Xaml.UnitTests/Converters/PointsListTypeConverterTests.cs

@ -1,5 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Avalonia.Controls.Shapes; using Avalonia.Controls.Shapes;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Converters; using Avalonia.Markup.Xaml.Converters;
using Xunit; using Xunit;
@ -7,6 +9,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters
{ {
public class PointsListTypeConverterTests public class PointsListTypeConverterTests
{ {
static PointsListTypeConverterTests()
{
RuntimeHelpers.RunClassConstructor(typeof(RelativeSource).TypeHandle);
}
[Theory] [Theory]
[InlineData("1,2 3,4")] [InlineData("1,2 3,4")]
[InlineData("1 2 3 4")] [InlineData("1 2 3 4")]

Loading…
Cancel
Save