Browse Source

Give PriorityLevel a reference to its PriorityValue.

And directly call the LevelValueChanged method on it rather than using callbacks.
pull/494/merge
Steven Kirk 11 years ago
parent
commit
7b371f8d2d
  1. 32
      src/Perspex.Base/PriorityLevel.cs
  2. 80
      src/Perspex.Base/PriorityValue.cs

32
src/Perspex.Base/PriorityLevel.cs

@ -31,34 +31,22 @@ namespace Perspex
/// </remarks>
internal class PriorityLevel
{
/// <summary>
/// Method called when current value changes.
/// </summary>
private readonly Action<PriorityLevel> _changed;
/// <summary>
/// The current direct value.
/// </summary>
private PriorityValue _owner;
private object _directValue;
/// <summary>
/// The index of the next <see cref="PriorityBindingEntry"/>.
/// </summary>
private int _nextIndex;
/// <summary>
/// Initializes a new instance of the <see cref="PriorityLevel"/> class.
/// </summary>
/// <param name="owner">The owner.</param>
/// <param name="priority">The priority.</param>
/// <param name="mode">The precedence mode.</param>
/// <param name="changed">A method to be called when the current value changes.</param>
public PriorityLevel(
int priority,
Action<PriorityLevel> changed)
PriorityValue owner,
int priority)
{
Contract.Requires<ArgumentNullException>(changed != null);
Contract.Requires<ArgumentNullException>(owner != null);
_changed = changed;
_owner = owner;
Priority = priority;
Value = _directValue = PerspexProperty.UnsetValue;
ActiveBindingIndex = -1;
@ -83,7 +71,7 @@ namespace Perspex
set
{
Value = _directValue = value;
_changed(this);
_owner.LevelValueChanged(this);
}
}
@ -141,7 +129,7 @@ namespace Perspex
{
Value = entry.Value;
ActiveBindingIndex = entry.Index;
_changed(this);
_owner.LevelValueChanged(this);
}
else
{
@ -175,14 +163,14 @@ namespace Perspex
{
Value = binding.Value;
ActiveBindingIndex = binding.Index;
_changed(this);
_owner.LevelValueChanged(this);
return;
}
}
Value = DirectValue;
ActiveBindingIndex = -1;
_changed(this);
_owner.LevelValueChanged(this);
}
}
}

80
src/Perspex.Base/PriorityValue.cs

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Subjects;
using System.Text;
using Perspex.Logging;
using Perspex.Utilities;
@ -21,34 +20,15 @@ namespace Perspex
/// priority binding that doesn't return <see cref="PerspexProperty.UnsetValue"/>. Where there
/// are multiple bindings registered with the same priority, the most recently added binding
/// has a higher priority. Each time the value changes, the
/// <see cref="IPriorityValueOwner.Changed(PerspexProperty, object, object)"/> method on the
/// <see cref="IPriorityValueOwner.Changed(PriorityValue, object, object)"/> method on the
/// owner object is fired with the old and new values.
/// </remarks>
internal class PriorityValue
{
/// <summary>
/// The owner of the object.
/// </summary>
private readonly IPriorityValueOwner _owner;
/// <summary>
/// The value type.
/// </summary>
private readonly Type _valueType;
/// <summary>
/// The currently registered bindings organised by priority.
/// </summary>
private readonly Dictionary<int, PriorityLevel> _levels = new Dictionary<int, PriorityLevel>();
/// <summary>
/// The current value.
/// </summary>
private object _value;
/// <summary>
/// The function used to validate the value, if any.
/// </summary>
private readonly Func<object, object> _validate;
/// <summary>
@ -169,6 +149,34 @@ namespace Perspex
return b.ToString();
}
/// <summary>
/// Called when the value for a priority level changes.
/// </summary>
/// <param name="level">The priority level of the changed entry.</param>
public void LevelValueChanged(PriorityLevel level)
{
if (level.Priority <= ValuePriority)
{
if (level.Value != PerspexProperty.UnsetValue)
{
UpdateValue(level.Value, level.Priority);
}
else
{
foreach (var i in _levels.Values.OrderBy(x => x.Priority))
{
if (i.Value != PerspexProperty.UnsetValue)
{
UpdateValue(i.Value, i.Priority);
return;
}
}
UpdateValue(PerspexProperty.UnsetValue, int.MaxValue);
}
}
}
/// <summary>
/// Causes a revalidation of the value.
/// </summary>
@ -197,7 +205,7 @@ namespace Perspex
if (!_levels.TryGetValue(priority, out result))
{
result = new PriorityLevel(priority, ValueChanged);
result = new PriorityLevel(this, priority);
_levels.Add(priority, result);
}
@ -238,33 +246,5 @@ namespace Perspex
value.GetType());
}
}
/// <summary>
/// Called when the value for a priority level changes.
/// </summary>
/// <param name="level">The priority level of the changed entry.</param>
private void ValueChanged(PriorityLevel level)
{
if (level.Priority <= ValuePriority)
{
if (level.Value != PerspexProperty.UnsetValue)
{
UpdateValue(level.Value, level.Priority);
}
else
{
foreach (var i in _levels.Values.OrderBy(x => x.Priority))
{
if (i.Value != PerspexProperty.UnsetValue)
{
UpdateValue(i.Value, i.Priority);
return;
}
}
UpdateValue(PerspexProperty.UnsetValue, int.MaxValue);
}
}
}
}
}

Loading…
Cancel
Save