A cross-platform UI framework for .NET
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.
 
 
 

103 lines
3.0 KiB

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Data;
using Avalonia.Utilities;
using static Avalonia.Rendering.Composition.Animations.PropertySetSnapshot;
namespace Avalonia.PropertyStore
{
internal abstract class ValueFrame
{
private List<IValueEntry>? _entries;
private AvaloniaPropertyDictionary<IValueEntry> _index;
private ValueStore? _owner;
private bool _isShared;
public int EntryCount => _index.Count;
public bool IsActive => GetIsActive(out _);
public ValueStore? Owner => !_isShared ? _owner :
throw new AvaloniaInternalException("Cannot get owner for shared ValueFrame");
public BindingPriority Priority { get; protected set; }
public bool Contains(AvaloniaProperty property) => _index.ContainsKey(property);
public IValueEntry GetEntry(int index) => _entries?[index] ?? _index[0];
public void SetOwner(ValueStore? owner)
{
if (_owner is not null && owner is not null)
throw new AvaloniaInternalException("ValueFrame already has an owner.");
if (!_isShared)
_owner = owner;
}
public bool TryGetEntryIfActive(
AvaloniaProperty property,
[NotNullWhen(true)] out IValueEntry? entry,
out bool activeChanged)
{
if (_index.TryGetValue(property, out entry))
return GetIsActive(out activeChanged);
activeChanged = false;
return false;
}
public void OnBindingCompleted(IValueEntry binding)
{
var property = binding.Property;
Remove(property);
Owner?.OnValueEntryRemoved(this, property);
}
public virtual void Dispose()
{
for (var i = 0; i < _index.Count; ++i)
_index[i].Unsubscribe();
}
protected abstract bool GetIsActive(out bool hasChanged);
protected void MakeShared()
{
_isShared = true;
_owner = null;
}
protected void Add(IValueEntry value)
{
Debug.Assert(!value.Property.IsDirect);
if (_entries is null && _index.Count == 1)
{
_entries = new();
_entries.Add(_index[0]);
}
_index.Add(value.Property, value);
_entries?.Add(value);
}
protected void Remove(AvaloniaProperty property)
{
Debug.Assert(!property.IsDirect);
if (_entries is not null)
{
var count = _entries.Count;
for (var i = 0; i < count; ++i)
{
if (_entries[i].Property == property)
{
_entries.RemoveAt(i);
break;
}
}
}
_index.Remove(property);
}
}
}