Browse Source

Make template bindings complete on Template change.

This fixes a leak - needs to be done in XAML as well though.
pull/366/head
Steven Kirk 10 years ago
parent
commit
e402eb8cdd
  1. 14
      src/Perspex.Base/BindingDescriptor.cs
  2. 19
      src/Perspex.Base/PerspexObject.cs
  3. 17
      src/Perspex.Controls/Primitives/TemplatedControl.cs

14
src/Perspex.Base/BindingDescriptor.cs

@ -78,6 +78,18 @@ namespace Perspex
set;
}
/// <summary>
/// Gets or sets the source observable.
/// </summary>
/// <remarks>
/// If null, then <see cref="Source"/>.<see cref="Property"/> will be used.
/// </remarks>
public IObservable<object> SourceObservable
{
get;
set;
}
/// <summary>
/// Gets a description of the binding.
/// </summary>
@ -128,7 +140,7 @@ namespace Perspex
/// <inheritdoc/>
protected override IDisposable SubscribeCore(IObserver<object> observer)
{
return Source.GetObservable(Property).Subscribe(observer);
return (SourceObservable ?? Source.GetObservable(Property)).Subscribe(observer);
}
}
}

19
src/Perspex.Base/PerspexObject.cs

@ -163,13 +163,7 @@ namespace Perspex
{
get
{
return new BindingDescriptor
{
Mode = binding.Mode,
Priority = binding.Priority,
Property = binding.Property,
Source = this,
};
return CreateBindingDescriptor(binding);
}
set
@ -203,6 +197,17 @@ namespace Perspex
}
}
protected virtual BindingDescriptor CreateBindingDescriptor(BindingDescriptor source)
{
return new BindingDescriptor
{
Mode = source.Mode,
Priority = source.Priority,
Property = source.Property,
Source = this,
};
}
public bool CheckAccess() => Dispatcher.UIThread.CheckAccess();
public void VerifyAccess() => Dispatcher.UIThread.VerifyAccess();

17
src/Perspex.Controls/Primitives/TemplatedControl.cs

@ -3,6 +3,7 @@
using System;
using System.Linq;
using System.Reactive.Linq;
using Perspex.Controls.Presenters;
using Perspex.Controls.Templates;
using Perspex.Media;
@ -211,6 +212,22 @@ namespace Perspex.Controls.Primitives
}
}
protected sealed override BindingDescriptor CreateBindingDescriptor(BindingDescriptor source)
{
var result = base.CreateBindingDescriptor(source);
// If the binding is a template binding, then complete when the Template changes.
if (source.Priority == BindingPriority.TemplatedParent)
{
var templateChanged = GetObservable(TemplateProperty).Skip(1);
result.SourceObservable = result.Source.GetObservable(result.Property)
.TakeUntil(templateChanged);
}
return result;
}
/// <summary>
/// Called when the control's template is applied.
/// </summary>

Loading…
Cancel
Save