csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.6 KiB
119 lines
3.6 KiB
using System;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using Avalonia.Styling.Activators;
|
|
|
|
#nullable enable
|
|
|
|
namespace Avalonia.Styling
|
|
{
|
|
/// <summary>
|
|
/// A selector that matches the common case of a type and/or name followed by a collection of
|
|
/// style classes and pseudoclasses.
|
|
/// </summary>
|
|
internal class PropertyEqualsSelector : Selector
|
|
{
|
|
private readonly Selector? _previous;
|
|
private readonly AvaloniaProperty _property;
|
|
private readonly object? _value;
|
|
private string? _selectorString;
|
|
|
|
public PropertyEqualsSelector(Selector? previous, AvaloniaProperty property, object? value)
|
|
{
|
|
property = property ?? throw new ArgumentNullException(nameof(property));
|
|
|
|
_previous = previous;
|
|
_property = property;
|
|
_value = value;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override bool InTemplate => _previous?.InTemplate ?? false;
|
|
|
|
/// <inheritdoc/>
|
|
public override bool IsCombinator => false;
|
|
|
|
/// <inheritdoc/>
|
|
public override Type? TargetType => _previous?.TargetType;
|
|
|
|
/// <inheritdoc/>
|
|
public override string ToString()
|
|
{
|
|
if (_selectorString == null)
|
|
{
|
|
var builder = new StringBuilder();
|
|
|
|
if (_previous != null)
|
|
{
|
|
builder.Append(_previous.ToString());
|
|
}
|
|
|
|
builder.Append('[');
|
|
|
|
if (_property.IsAttached)
|
|
{
|
|
builder.Append('(');
|
|
builder.Append(_property.OwnerType.Name);
|
|
builder.Append('.');
|
|
}
|
|
|
|
builder.Append(_property.Name);
|
|
if (_property.IsAttached)
|
|
{
|
|
builder.Append(')');
|
|
}
|
|
builder.Append('=');
|
|
builder.Append(_value ?? string.Empty);
|
|
builder.Append(']');
|
|
|
|
_selectorString = builder.ToString();
|
|
}
|
|
|
|
return _selectorString;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe)
|
|
{
|
|
if (subscribe)
|
|
{
|
|
return new SelectorMatch(new PropertyEqualsActivator(control, _property, _value));
|
|
}
|
|
else
|
|
{
|
|
return Compare(_property.PropertyType, control.GetValue(_property), _value)
|
|
? SelectorMatch.AlwaysThisInstance
|
|
: SelectorMatch.NeverThisInstance;
|
|
}
|
|
|
|
}
|
|
|
|
protected override Selector? MovePrevious() => _previous;
|
|
protected override Selector? MovePreviousOrParent() => _previous;
|
|
|
|
internal static bool Compare(Type propertyType, object? propertyValue, object? value)
|
|
{
|
|
if (propertyType == typeof(object) &&
|
|
propertyValue?.GetType() is Type inferredType)
|
|
{
|
|
propertyType = inferredType;
|
|
}
|
|
|
|
var valueType = value?.GetType();
|
|
|
|
if (valueType is null || propertyType.IsAssignableFrom(valueType))
|
|
{
|
|
return Equals(propertyValue, value);
|
|
}
|
|
|
|
var converter = TypeDescriptor.GetConverter(propertyType);
|
|
if (converter?.CanConvertFrom(valueType) == true)
|
|
{
|
|
return Equals(propertyValue, converter.ConvertFrom(null, CultureInfo.InvariantCulture, value!));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|