Browse Source

Merge pull request #8676 from AvaloniaUI/fixes/8672-multibinding-unsetvalue

Tweak TemplateBinding Initialization
pull/8680/head
Max Katz 4 years ago
committed by GitHub
parent
commit
089e417977
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Markup/Avalonia.Markup/Data/TemplateBinding.cs
  2. 43
      tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs

5
src/Markup/Avalonia.Markup/Data/TemplateBinding.cs

@ -19,6 +19,7 @@ namespace Avalonia.Data
private bool _isSetterValue;
private IStyledElement _target = default!;
private Type? _targetType;
private bool _hasProducedValue;
public TemplateBinding()
{
@ -143,10 +144,12 @@ namespace Avalonia.Data
}
PublishNext(value);
_hasProducedValue = true;
}
else
else if (_hasProducedValue)
{
PublishNext(AvaloniaProperty.UnsetValue);
_hasProducedValue = false;
}
}

43
tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Avalonia.Controls;
@ -217,6 +218,37 @@ namespace Avalonia.Markup.UnitTests.Data
}
}
[Fact]
public void Should_Not_Pass_UnsetValue_To_MultiBinding_During_ApplyTemplate()
{
var converter = new MultiConverter();
var source = new Button
{
Content = "foo",
Template = new FuncControlTemplate<Button>((parent, _) =>
new ContentPresenter
{
[~ContentPresenter.ContentProperty] = new MultiBinding
{
Converter = converter,
Bindings =
{
new TemplateBinding(ContentControl.ContentProperty),
}
}
}),
};
source.ApplyTemplate();
var target = (ContentPresenter)source.GetVisualChildren().Single();
// #8672 was caused by TemplateBinding passing "unset" to the MultiBinding during
// ApplyTemplate as the TemplatedParent property doesn't get setup until after the
// binding is initiated.
Assert.Equal(new[] { "foo" }, converter.Values);
}
private class PrefixConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
@ -247,5 +279,16 @@ namespace Avalonia.Markup.UnitTests.Data
return null;
}
}
private class MultiConverter : IMultiValueConverter
{
public List<object> Values { get; } = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{
Values.AddRange(values);
return values.FirstOrDefault();
}
}
}
}

Loading…
Cancel
Save