| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using System;
- using Avalonia.Data;
- using Avalonia.Reactive;
- #nullable enable
- namespace Avalonia
- {
- /// <summary>
- /// Base class for direct properties.
- /// </summary>
- /// <typeparam name="TValue">The type of the property's value.</typeparam>
- /// <remarks>
- /// Whereas <see cref="DirectProperty{TOwner, TValue}"/> is typed on the owner type, this base
- /// class provides a non-owner-typed interface to a direct poperty.
- /// </remarks>
- public abstract class DirectPropertyBase<TValue> : AvaloniaProperty<TValue>
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="DirectPropertyBase{TValue}"/> class.
- /// </summary>
- /// <param name="name">The name of the property.</param>
- /// <param name="ownerType">The type of the class that registers the property.</param>
- /// <param name="metadata">The property metadata.</param>
- /// <param name="enableDataValidation">
- /// Whether the property is interested in data validation.
- /// </param>
- protected DirectPropertyBase(
- string name,
- Type ownerType,
- PropertyMetadata metadata,
- bool enableDataValidation)
- : base(name, ownerType, metadata)
- {
- IsDataValidationEnabled = enableDataValidation;
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="AvaloniaProperty"/> class.
- /// </summary>
- /// <param name="source">The property to copy.</param>
- /// <param name="ownerType">The new owner type.</param>
- /// <param name="metadata">Optional overridden metadata.</param>
- /// <param name="enableDataValidation">
- /// Whether the property is interested in data validation.
- /// </param>
- protected DirectPropertyBase(
- AvaloniaProperty source,
- Type ownerType,
- PropertyMetadata metadata,
- bool enableDataValidation)
- : base(source, ownerType, metadata)
- {
- IsDataValidationEnabled = enableDataValidation;
- }
- /// <summary>
- /// Gets the type that registered the property.
- /// </summary>
- public abstract Type Owner { get; }
- /// <summary>
- /// Gets a value that indicates whether data validation is enabled for the property.
- /// </summary>
- public bool IsDataValidationEnabled { get; }
- /// <summary>
- /// Gets the value of the property on the instance.
- /// </summary>
- /// <param name="instance">The instance.</param>
- /// <returns>The property value.</returns>
- internal abstract TValue InvokeGetter(IAvaloniaObject instance);
- /// <summary>
- /// Sets the value of the property on the instance.
- /// </summary>
- /// <param name="instance">The instance.</param>
- /// <param name="value">The value.</param>
- internal abstract void InvokeSetter(IAvaloniaObject instance, BindingValue<TValue> value);
- /// <summary>
- /// Gets the unset value for the property on the specified type.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <returns>The unset value.</returns>
- public TValue GetUnsetValue(Type type)
- {
- type = type ?? throw new ArgumentNullException(nameof(type));
- return GetMetadata(type).UnsetValue;
- }
- /// <summary>
- /// Gets the property metadata for the specified type.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <returns>
- /// The property metadata.
- /// </returns>
- public new DirectPropertyMetadata<TValue> GetMetadata(Type type)
- {
- return (DirectPropertyMetadata<TValue>)base.GetMetadata(type);
- }
- /// <inheritdoc/>
- internal override void NotifyInitialized(IAvaloniaObject o)
- {
- if (HasNotifyInitializedObservers)
- {
- var e = new AvaloniaPropertyChangedEventArgs<TValue>(
- o,
- this,
- default,
- InvokeGetter(o),
- BindingPriority.Unset);
- NotifyInitialized(e);
- }
- }
- /// <inheritdoc/>
- internal override object? RouteGetValue(IAvaloniaObject o)
- {
- return o.GetValue<TValue>(this);
- }
- /// <inheritdoc/>
- internal override void RouteSetValue(
- IAvaloniaObject o,
- object value,
- BindingPriority priority)
- {
- var v = TryConvert(value);
- if (v.HasValue)
- {
- o.SetValue<TValue>(this, (TValue)v.Value, priority);
- }
- else if (v.Type == BindingValueType.UnsetValue)
- {
- o.ClearValue(this);
- }
- else if (v.HasError)
- {
- throw v.Error!;
- }
- }
- /// <inheritdoc/>
- internal override IDisposable RouteBind(
- IAvaloniaObject o,
- IObservable<BindingValue<object>> source,
- BindingPriority priority)
- {
- var adapter = TypedBindingAdapter<TValue>.Create(o, this, source);
- return o.Bind<TValue>(this, adapter, priority);
- }
- internal override void RouteInheritanceParentChanged(AvaloniaObject o, IAvaloniaObject oldParent)
- {
- throw new NotSupportedException("Direct properties do not support inheritance.");
- }
- }
- }
|