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

80
src/Perspex.Base/PriorityValue.cs

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Subjects;
using System.Text; using System.Text;
using Perspex.Logging; using Perspex.Logging;
using Perspex.Utilities; using Perspex.Utilities;
@ -21,34 +20,15 @@ namespace Perspex
/// priority binding that doesn't return <see cref="PerspexProperty.UnsetValue"/>. Where there /// 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 /// are multiple bindings registered with the same priority, the most recently added binding
/// has a higher priority. Each time the value changes, the /// 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. /// owner object is fired with the old and new values.
/// </remarks> /// </remarks>
internal class PriorityValue internal class PriorityValue
{ {
/// <summary>
/// The owner of the object.
/// </summary>
private readonly IPriorityValueOwner _owner; private readonly IPriorityValueOwner _owner;
/// <summary>
/// The value type.
/// </summary>
private readonly Type _valueType; private readonly Type _valueType;
/// <summary>
/// The currently registered bindings organised by priority.
/// </summary>
private readonly Dictionary<int, PriorityLevel> _levels = new Dictionary<int, PriorityLevel>(); private readonly Dictionary<int, PriorityLevel> _levels = new Dictionary<int, PriorityLevel>();
/// <summary>
/// The current value.
/// </summary>
private object _value; private object _value;
/// <summary>
/// The function used to validate the value, if any.
/// </summary>
private readonly Func<object, object> _validate; private readonly Func<object, object> _validate;
/// <summary> /// <summary>
@ -169,6 +149,34 @@ namespace Perspex
return b.ToString(); 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> /// <summary>
/// Causes a revalidation of the value. /// Causes a revalidation of the value.
/// </summary> /// </summary>
@ -197,7 +205,7 @@ namespace Perspex
if (!_levels.TryGetValue(priority, out result)) if (!_levels.TryGetValue(priority, out result))
{ {
result = new PriorityLevel(priority, ValueChanged); result = new PriorityLevel(this, priority);
_levels.Add(priority, result); _levels.Add(priority, result);
} }
@ -238,33 +246,5 @@ namespace Perspex
value.GetType()); 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