Browse Source

Merge branch 'master' into fixes/datagrid-columns-displayindex

pull/5180/head
Max Katz 5 years ago
committed by GitHub
parent
commit
d525984c71
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      samples/ControlCatalog/Pages/SliderPage.xaml
  2. 27
      samples/ControlCatalog/Pages/ToolTipPage.xaml
  3. 5
      src/Avalonia.Base/Data/Core/SettableNode.cs
  4. 40
      src/Avalonia.Controls/ToolTip.cs
  5. 10
      src/Avalonia.Controls/ToolTipService.cs
  6. 5
      src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/StringIndexerNode.cs
  7. 20
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs

14
samples/ControlCatalog/Pages/SliderPage.xaml

@ -22,6 +22,20 @@
IsSnapToTickEnabled="True"
Ticks="0,20,25,40,75,100"
Width="300" />
<Slider Name="SliderWithTooltip"
Value="0"
Minimum="0"
Maximum="100"
Width="300">
<Slider.Styles>
<Style Selector="Slider /template/ Thumb">
<Setter Property="ToolTip.Tip" Value="{Binding $parent[Slider].Value, Mode=OneWay, StringFormat='Value \{0:f\}'}" />
<Setter Property="ToolTip.Placement" Value="Top" />
<Setter Property="ToolTip.VerticalOffset" Value="-10" />
<Setter Property="ToolTip.HorizontalOffset" Value="-30" />
</Style>
</Slider.Styles>
</Slider>
<Slider Value="0"
Minimum="0"
Maximum="100"

27
samples/ControlCatalog/Pages/ToolTipPage.xaml

@ -6,7 +6,7 @@
<TextBlock Classes="h1">ToolTip</TextBlock>
<TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock>
<Grid RowDefinitions="Auto,Auto"
<Grid RowDefinitions="Auto,Auto,Auto"
ColumnDefinitions="Auto,Auto"
Margin="0,16,0,0"
HorizontalAlignment="Center">
@ -38,6 +38,31 @@
</ToolTip.Tip>
<TextBlock>ToolTip bottom placement</TextBlock>
</Border>
<Border Grid.Row="2"
Grid.ColumnSpan="2"
Background="{DynamicResource SystemAccentColor}"
Margin="5"
Padding="50"
ToolTip.Tip="Hello"
ToolTip.Placement="Top">
<Border.Styles>
<Style Selector="Border">
<Style.Animations>
<Animation Duration="0:0:2" IterationCount="Infinite">
<KeyFrame KeyTime="0:0:0">
<Setter Property="ToolTip.HorizontalOffset" Value="0" />
<Setter Property="ToolTip.VerticalOffset" Value="-50" />
</KeyFrame>
<KeyFrame KeyTime="0:0:2" >
<Setter Property="ToolTip.HorizontalOffset" Value="100" />
<Setter Property="ToolTip.VerticalOffset" Value="50" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Border.Styles>
<TextBlock>Moving offset</TextBlock>
</Border>
</Grid>
</StackPanel>
</UserControl>

5
src/Avalonia.Base/Data/Core/SettableNode.cs

@ -15,7 +15,8 @@ namespace Avalonia.Data.Core
private bool ShouldNotSet(object value)
{
if (PropertyType == null)
var propertyType = PropertyType;
if (propertyType == null)
{
return false;
}
@ -37,7 +38,7 @@ namespace Avalonia.Data.Core
return false;
}
if (PropertyType.IsValueType)
if (propertyType.IsValueType)
{
return lastValue.Equals(value);
}

40
src/Avalonia.Controls/ToolTip.cs

@ -1,3 +1,4 @@
#nullable enable
using System;
using System.Reactive.Linq;
using Avalonia.Controls.Metadata;
@ -21,8 +22,8 @@ namespace Avalonia.Controls
/// <summary>
/// Defines the ToolTip.Tip attached property.
/// </summary>
public static readonly AttachedProperty<object> TipProperty =
AvaloniaProperty.RegisterAttached<ToolTip, Control, object>("Tip");
public static readonly AttachedProperty<object?> TipProperty =
AvaloniaProperty.RegisterAttached<ToolTip, Control, object?>("Tip");
/// <summary>
/// Defines the ToolTip.IsOpen attached property.
@ -57,10 +58,10 @@ namespace Avalonia.Controls
/// <summary>
/// Stores the current <see cref="ToolTip"/> instance in the control.
/// </summary>
internal static readonly AttachedProperty<ToolTip> ToolTipProperty =
AvaloniaProperty.RegisterAttached<ToolTip, Control, ToolTip>("ToolTip");
internal static readonly AttachedProperty<ToolTip?> ToolTipProperty =
AvaloniaProperty.RegisterAttached<ToolTip, Control, ToolTip?>("ToolTip");
private IPopupHost _popup;
private IPopupHost? _popup;
/// <summary>
/// Initializes static members of the <see cref="ToolTip"/> class.
@ -70,6 +71,10 @@ namespace Avalonia.Controls
TipProperty.Changed.Subscribe(ToolTipService.Instance.TipChanged);
IsOpenProperty.Changed.Subscribe(ToolTipService.Instance.TipOpenChanged);
IsOpenProperty.Changed.Subscribe(IsOpenChanged);
HorizontalOffsetProperty.Changed.Subscribe(RecalculatePositionOnPropertyChanged);
VerticalOffsetProperty.Changed.Subscribe(RecalculatePositionOnPropertyChanged);
PlacementProperty.Changed.Subscribe(RecalculatePositionOnPropertyChanged);
}
/// <summary>
@ -79,7 +84,7 @@ namespace Avalonia.Controls
/// <returns>
/// The content to be displayed in the control's tooltip.
/// </returns>
public static object GetTip(Control element)
public static object? GetTip(Control element)
{
return element.GetValue(TipProperty);
}
@ -89,7 +94,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="element">The control to get the property from.</param>
/// <param name="value">The content to be displayed in the control's tooltip.</param>
public static void SetTip(Control element, object value)
public static void SetTip(Control element, object? value)
{
element.SetValue(TipProperty, value);
}
@ -207,8 +212,8 @@ namespace Avalonia.Controls
private static void IsOpenChanged(AvaloniaPropertyChangedEventArgs e)
{
var control = (Control)e.Sender;
var newValue = (bool)e.NewValue;
ToolTip toolTip;
var newValue = (bool)e.NewValue!;
ToolTip? toolTip;
if (newValue)
{
@ -235,6 +240,23 @@ namespace Avalonia.Controls
toolTip?.UpdatePseudoClasses(newValue);
}
private static void RecalculatePositionOnPropertyChanged(AvaloniaPropertyChangedEventArgs args)
{
var control = (Control)args.Sender;
var tooltip = control.GetValue(ToolTipProperty);
if (tooltip == null)
{
return;
}
tooltip.RecalculatePosition(control);
}
internal void RecalculatePosition(Control control)
{
_popup?.ConfigurePosition(control, GetPlacement(control), new Point(GetHorizontalOffset(control), GetVerticalOffset(control)));
}
private void Open(Control control)
{
Close();

10
src/Avalonia.Controls/ToolTipService.cs

@ -51,10 +51,12 @@ namespace Avalonia.Controls
if (e.OldValue is false && e.NewValue is true)
{
control.DetachedFromVisualTree += ControlDetaching;
control.EffectiveViewportChanged += ControlEffectiveViewportChanged;
}
else if(e.OldValue is true && e.NewValue is false)
{
control.DetachedFromVisualTree -= ControlDetaching;
control.EffectiveViewportChanged -= ControlEffectiveViewportChanged;
}
}
@ -62,6 +64,7 @@ namespace Avalonia.Controls
{
var control = (Control)sender;
control.DetachedFromVisualTree -= ControlDetaching;
control.EffectiveViewportChanged -= ControlEffectiveViewportChanged;
Close(control);
}
@ -97,6 +100,13 @@ namespace Avalonia.Controls
Close(control);
}
private void ControlEffectiveViewportChanged(object sender, Layout.EffectiveViewportChangedEventArgs e)
{
var control = (Control)sender;
var toolTip = control.GetValue(ToolTip.ToolTipProperty);
toolTip?.RecalculatePosition(control);
}
private void StartShowTimer(int showDelay, Control control)
{
_timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(showDelay) };

5
src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/StringIndexerNode.cs

@ -129,7 +129,10 @@ namespace Avalonia.Markup.Parsers.Nodes
{
get
{
Target.TryGetTarget(out object target);
if (!Target.TryGetTarget(out object target))
{
return null;
}
return GetIndexer(target.GetType().GetTypeInfo())?.PropertyType;
}

20
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs

@ -4,6 +4,8 @@ using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Logging;
using Avalonia.Platform;
@ -797,6 +799,24 @@ namespace Avalonia.Base.UnitTests
Assert.False(source.SetterCalled);
}
[Fact]
public void TwoWay_Binding_Should_Not_Fail_With_Null_DataContext()
{
var target = new TextBlock();
target.DataContext = null;
target.Bind(TextBlock.TextProperty, new Binding("Missing", BindingMode.TwoWay));
}
[Fact]
public void TwoWay_Binding_Should_Not_Fail_With_Null_DataContext_Indexer()
{
var target = new TextBlock();
target.DataContext = null;
target.Bind(TextBlock.TextProperty, new Binding("[0]", BindingMode.TwoWay));
}
[Fact]
public void Disposing_Completed_Binding_Does_Not_Throw()
{

Loading…
Cancel
Save