Remove AutoCompleteBox.BindingEvaluator (#20596)
* Remove AutoCompleteBox.BindingEvaluator * Fix AutoCompleteBoxPage sample * Update API suppressions
This commit is contained in:
committed by
GitHub
parent
d670efd162
commit
313bceea90
@@ -31,6 +31,12 @@
|
|||||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||||
</Suppression>
|
</Suppression>
|
||||||
|
<Suppression>
|
||||||
|
<DiagnosticId>CP0001</DiagnosticId>
|
||||||
|
<Target>T:Avalonia.Controls.AutoCompleteBox.BindingEvaluator`1</Target>
|
||||||
|
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||||
|
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||||
|
</Suppression>
|
||||||
<Suppression>
|
<Suppression>
|
||||||
<DiagnosticId>CP0001</DiagnosticId>
|
<DiagnosticId>CP0001</DiagnosticId>
|
||||||
<Target>T:Avalonia.Controls.NativeMenuItemToggleType</Target>
|
<Target>T:Avalonia.Controls.NativeMenuItemToggleType</Target>
|
||||||
@@ -79,6 +85,12 @@
|
|||||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||||
</Suppression>
|
</Suppression>
|
||||||
|
<Suppression>
|
||||||
|
<DiagnosticId>CP0001</DiagnosticId>
|
||||||
|
<Target>T:Avalonia.Controls.AutoCompleteBox.BindingEvaluator`1</Target>
|
||||||
|
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||||
|
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||||
|
</Suppression>
|
||||||
<Suppression>
|
<Suppression>
|
||||||
<DiagnosticId>CP0001</DiagnosticId>
|
<DiagnosticId>CP0001</DiagnosticId>
|
||||||
<Target>T:Avalonia.Controls.NativeMenuItemToggleType</Target>
|
<Target>T:Avalonia.Controls.NativeMenuItemToggleType</Target>
|
||||||
|
|||||||
@@ -7,30 +7,12 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
using Avalonia.LogicalTree;
|
using Avalonia.LogicalTree;
|
||||||
|
using ControlCatalog.Models;
|
||||||
|
|
||||||
namespace ControlCatalog.Pages
|
namespace ControlCatalog.Pages
|
||||||
{
|
{
|
||||||
public partial class AutoCompleteBoxPage : UserControl
|
public partial class AutoCompleteBoxPage : UserControl
|
||||||
{
|
{
|
||||||
public class StateData
|
|
||||||
{
|
|
||||||
public string Name { get; private set; }
|
|
||||||
public string Abbreviation { get; private set; }
|
|
||||||
public string Capital { get; private set; }
|
|
||||||
|
|
||||||
public StateData(string name, string abbreviatoin, string capital)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Abbreviation = abbreviatoin;
|
|
||||||
Capital = capital;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static StateData[] BuildAllStates()
|
private static StateData[] BuildAllStates()
|
||||||
{
|
{
|
||||||
return new StateData[]
|
return new StateData[]
|
||||||
|
|||||||
@@ -191,6 +191,12 @@ namespace Avalonia.Controls
|
|||||||
public static readonly StyledProperty<object?> InnerRightContentProperty =
|
public static readonly StyledProperty<object?> InnerRightContentProperty =
|
||||||
TextBox.InnerRightContentProperty.AddOwner<AutoCompleteBox>();
|
TextBox.InnerRightContentProperty.AddOwner<AutoCompleteBox>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the <see cref="ValueMemberBinding" /> property.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly StyledProperty<BindingBase?> ValueMemberBindingProperty =
|
||||||
|
AvaloniaProperty.Register<AutoCompleteBox, BindingBase?>(nameof(ValueMemberBinding));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the caret index
|
/// Gets or sets the caret index
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -311,26 +317,16 @@ namespace Avalonia.Controls
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="T:Avalonia.Data.Binding" /> that
|
/// Gets or sets the <see cref="BindingBase" /> that is used to get the values for display in the text portion
|
||||||
/// is used to get the values for display in the text portion of
|
/// of the <see cref="AutoCompleteBox" /> control.
|
||||||
/// the <see cref="AutoCompleteBox" />
|
|
||||||
/// control.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The <see cref="T:Avalonia.Data.IBinding" /> object used
|
/// <value>The <see cref="T:Avalonia.Data.BindingBase" /> object used when binding to a collection property.</value>
|
||||||
/// when binding to a collection property.</value>
|
|
||||||
[AssignBinding]
|
[AssignBinding]
|
||||||
[InheritDataTypeFromItems(nameof(ItemsSource))]
|
[InheritDataTypeFromItems(nameof(ItemsSource))]
|
||||||
public BindingBase? ValueMemberBinding
|
public BindingBase? ValueMemberBinding
|
||||||
{
|
{
|
||||||
get => _valueBindingEvaluator?.ValueBinding;
|
get => GetValue(ValueMemberBindingProperty);
|
||||||
set
|
set => SetValue(ValueMemberBindingProperty, value);
|
||||||
{
|
|
||||||
if (ValueMemberBinding != value)
|
|
||||||
{
|
|
||||||
_valueBindingEvaluator = new BindingEvaluator<string>(value);
|
|
||||||
OnValueMemberBindingChanged(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ namespace Avalonia.Controls
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A control that can provide updated string values from a binding.
|
/// A control that can provide updated string values from a binding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private BindingEvaluator<string>? _valueBindingEvaluator;
|
private BindingEvaluator<string?>? _valueMemberBindingEvaluator;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A weak subscription for the collection changed event.
|
/// A weak subscription for the collection changed event.
|
||||||
@@ -439,6 +439,7 @@ namespace Avalonia.Controls
|
|||||||
if (!_settingItemTemplateFromValueMemberBinding)
|
if (!_settingItemTemplateFromValueMemberBinding)
|
||||||
_itemTemplateIsFromValueMemberBinding = false;
|
_itemTemplateIsFromValueMemberBinding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnValueMemberBindingChanged(BindingBase? value)
|
private void OnValueMemberBindingChanged(BindingBase? value)
|
||||||
{
|
{
|
||||||
if (_itemTemplateIsFromValueMemberBinding)
|
if (_itemTemplateIsFromValueMemberBinding)
|
||||||
@@ -460,6 +461,16 @@ namespace Avalonia.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(change);
|
||||||
|
|
||||||
|
if (change.Property == ValueMemberBindingProperty)
|
||||||
|
{
|
||||||
|
OnValueMemberBindingChanged(change.GetNewValue<BindingBase?>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static AutoCompleteBox()
|
static AutoCompleteBox()
|
||||||
{
|
{
|
||||||
FocusableProperty.OverrideDefaultValue<AutoCompleteBox>(true);
|
FocusableProperty.OverrideDefaultValue<AutoCompleteBox>(true);
|
||||||
@@ -1181,25 +1192,6 @@ namespace Avalonia.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Formats an Item for text comparisons based on Converter
|
|
||||||
/// and ConverterCulture properties.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The object to format.</param>
|
|
||||||
/// <param name="clearDataContext">A value indicating whether to clear
|
|
||||||
/// the data context after the lookup is performed.</param>
|
|
||||||
/// <returns>Formatted Value.</returns>
|
|
||||||
private string? FormatValue(object? value, bool clearDataContext)
|
|
||||||
{
|
|
||||||
string? result = FormatValue(value);
|
|
||||||
if (clearDataContext && _valueBindingEvaluator != null)
|
|
||||||
{
|
|
||||||
_valueBindingEvaluator.ClearDataContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the specified object to a string by using the
|
/// Converts the specified object to a string by using the
|
||||||
/// <see cref="P:Avalonia.Data.Binding.Converter" /> and
|
/// <see cref="P:Avalonia.Data.Binding.Converter" /> and
|
||||||
@@ -1215,9 +1207,13 @@ namespace Avalonia.Controls
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected virtual string? FormatValue(object? value)
|
protected virtual string? FormatValue(object? value)
|
||||||
{
|
{
|
||||||
if (_valueBindingEvaluator != null)
|
if (ValueMemberBinding is { } valueMemberBinding)
|
||||||
{
|
{
|
||||||
return _valueBindingEvaluator.GetDynamicValue(value) ?? String.Empty;
|
_valueMemberBindingEvaluator ??= new();
|
||||||
|
_valueMemberBindingEvaluator.UpdateBinding(valueMemberBinding);
|
||||||
|
var result = _valueMemberBindingEvaluator.Evaluate(value) ?? string.Empty;
|
||||||
|
_valueMemberBindingEvaluator.ClearDataContext();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value == null ? String.Empty : value.ToString();
|
return value == null ? String.Empty : value.ToString();
|
||||||
@@ -1451,9 +1447,6 @@ namespace Avalonia.Controls
|
|||||||
|
|
||||||
_view?.Clear();
|
_view?.Clear();
|
||||||
_view?.AddRange(_newViewItems);
|
_view?.AddRange(_newViewItems);
|
||||||
|
|
||||||
// Clear the evaluator to discard a reference to the last item
|
|
||||||
_valueBindingEvaluator?.ClearDataContext();
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -1638,7 +1631,7 @@ namespace Avalonia.Controls
|
|||||||
if (top != null)
|
if (top != null)
|
||||||
{
|
{
|
||||||
newSelectedItem = top;
|
newSelectedItem = top;
|
||||||
string? topString = FormatValue(top, true);
|
string? topString = FormatValue(top);
|
||||||
|
|
||||||
// Only replace partially when the two words being the same
|
// Only replace partially when the two words being the same
|
||||||
int minLength = Math.Min(topString?.Length ?? 0, Text?.Length ?? 0);
|
int minLength = Math.Min(topString?.Length ?? 0, Text?.Length ?? 0);
|
||||||
@@ -1744,7 +1737,7 @@ namespace Avalonia.Controls
|
|||||||
}
|
}
|
||||||
else if (TextSelector != null)
|
else if (TextSelector != null)
|
||||||
{
|
{
|
||||||
text = TextSelector(SearchText, FormatValue(newItem, true));
|
text = TextSelector(SearchText, FormatValue(newItem));
|
||||||
}
|
}
|
||||||
else if (ItemSelector != null)
|
else if (ItemSelector != null)
|
||||||
{
|
{
|
||||||
@@ -1752,7 +1745,7 @@ namespace Avalonia.Controls
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text = FormatValue(newItem, true);
|
text = FormatValue(newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the Text property and the TextBox values
|
// Update the Text property and the TextBox values
|
||||||
@@ -2020,109 +2013,5 @@ namespace Avalonia.Controls
|
|||||||
return string.Equals(value, text, StringComparison.Ordinal);
|
return string.Equals(value, text, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO12: Remove, this shouldn't be part of the public API. Use our internal BindingEvaluator instead.
|
|
||||||
/// <summary>
|
|
||||||
/// A framework element that permits a binding to be evaluated in a new data
|
|
||||||
/// context leaf node.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of dynamic binding to return.</typeparam>
|
|
||||||
public class BindingEvaluator<T> : Control
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the string value binding used by the control.
|
|
||||||
/// </summary>
|
|
||||||
private BindingBase? _binding;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Identifies the Value dependency property.
|
|
||||||
/// </summary>
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1002:AvaloniaProperty objects should not be owned by a generic type",
|
|
||||||
Justification = "This property is not supposed to be used from XAML.")]
|
|
||||||
public static readonly StyledProperty<T> ValueProperty =
|
|
||||||
AvaloniaProperty.Register<BindingEvaluator<T>, T>(nameof(Value));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the data item value.
|
|
||||||
/// </summary>
|
|
||||||
public T Value
|
|
||||||
{
|
|
||||||
get => GetValue(ValueProperty);
|
|
||||||
set => SetValue(ValueProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the value binding.
|
|
||||||
/// </summary>
|
|
||||||
public BindingBase? ValueBinding
|
|
||||||
{
|
|
||||||
get => _binding;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_binding = value;
|
|
||||||
if (value is not null)
|
|
||||||
Bind(ValueProperty, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the BindingEvaluator class.
|
|
||||||
/// </summary>
|
|
||||||
public BindingEvaluator()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the BindingEvaluator class,
|
|
||||||
/// setting the initial binding to the provided parameter.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="binding">The initial string value binding.</param>
|
|
||||||
public BindingEvaluator(BindingBase? binding)
|
|
||||||
: this()
|
|
||||||
{
|
|
||||||
ValueBinding = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears the data context so that the control does not keep a
|
|
||||||
/// reference to the last-looked up item.
|
|
||||||
/// </summary>
|
|
||||||
public void ClearDataContext()
|
|
||||||
{
|
|
||||||
DataContext = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the data context of the framework element and returns the
|
|
||||||
/// updated binding value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="o">The object to use as the data context.</param>
|
|
||||||
/// <param name="clearDataContext">If set to true, this parameter will
|
|
||||||
/// clear the data context immediately after retrieving the value.</param>
|
|
||||||
/// <returns>Returns the evaluated T value of the bound dependency
|
|
||||||
/// property.</returns>
|
|
||||||
public T GetDynamicValue(object o, bool clearDataContext)
|
|
||||||
{
|
|
||||||
DataContext = o;
|
|
||||||
T value = Value;
|
|
||||||
if (clearDataContext)
|
|
||||||
{
|
|
||||||
DataContext = null;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the data context of the framework element and returns the
|
|
||||||
/// updated binding value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="o">The object to use as the data context.</param>
|
|
||||||
/// <returns>Returns the evaluated T value of the bound dependency
|
|
||||||
/// property.</returns>
|
|
||||||
public T GetDynamicValue(object? o)
|
|
||||||
{
|
|
||||||
DataContext = o;
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user