Skip to content

Commit

Permalink
add tracking of view bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
wendazhou committed Mar 26, 2013
1 parent 091226c commit 082f098
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
122 changes: 122 additions & 0 deletions ReactiveUI/BindingTrackerBindingHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ReactiveUI
{
public class BindingInfo
{
readonly ReadOnlyCollection<string> sourcePath;
readonly ReadOnlyCollection<string> targetPath;
readonly WeakReference source;
readonly WeakReference target;

public BindingInfo(object source, object target, IEnumerable<string> sourcePath, IEnumerable<string> targetPath)
{
this.sourcePath = sourcePath.ToList().AsReadOnly();
this.targetPath = targetPath.ToList().AsReadOnly();

this.source = new WeakReference(source);
this.target = new WeakReference(target);
}

public IEnumerable<string> SourcePath
{
get { return sourcePath; }
}

public IEnumerable<string> TargetPath
{
get { return targetPath; }
}

public WeakReference Source
{
get { return source; }
}

public WeakReference Target
{
get { return target; }
}
}

/// <summary>
/// This class implements a method of tracking all the bindings that are set on a given object.
/// </summary>
internal class BindingTrackerBindingHook : IPropertyBindingHook, IBindingRegistry, IEnableLogger
{
readonly Dictionary<object, List<BindingInfo>> allBindings = new Dictionary<object, List<BindingInfo>>();

public bool ExecuteHook(object source, object target,
Func<IObservedChange<object, object>[]> getCurrentViewModelProperties,
Func<IObservedChange<object, object>[]> getCurrentViewProperties,
BindingDirection direction)
{
if (!Monitor) {
// this is not active, don't do anything.
return true;
}

var sourcePath = getCurrentViewModelProperties().Select(x => x.PropertyName);
var targetPath = getCurrentViewProperties().Select(x => x.PropertyName);

var bindingInfo = new BindingInfo(source, target, sourcePath, targetPath);

lock (allBindings) {
List<BindingInfo> bindings;

if (!allBindings.TryGetValue(target, out bindings)) {
bindings = new List<BindingInfo>();
}

bindings.Add(bindingInfo);

allBindings[source] = bindings;
}

return true;
}

public IEnumerable<BindingInfo> GetBindingForView(object view)
{
if (!Monitor) {
this.Log().Warn("You are tryong to get bindings for a view object, " +
"but since monitoring is not enabled, they might be out of date!");
}

lock (allBindings) {
List<BindingInfo> bindings;

if (!allBindings.TryGetValue(view, out bindings)) {
return Enumerable.Empty<BindingInfo>();
}

var copyOfBindings = new BindingInfo[bindings.Count];
bindings.CopyTo(copyOfBindings);
return copyOfBindings;
}
}

public bool Monitor { get; set; }
}

public interface IBindingRegistry
{
/// <summary>
/// Gets a collection of all the bindings applied to a given <see cref="view"/>.
/// </summary>
/// <param name="view">The target object for which to get all the bindings for.</param>
/// <returns>An enumerable containing all the bindings applied to the <paramref name="view"/>.</returns>
IEnumerable<BindingInfo> GetBindingForView(object view);

/// <summary>
/// Sets a value indicating whether this instance of <see cref="IBindingRegistry"/>
/// should monitor the bindings.
/// </summary>
bool Monitor { get; set; }
}
}
1 change: 1 addition & 0 deletions ReactiveUI/ReactiveUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="BindingTrackerBindingHook.cs" />
<Compile Include="BindingTypeConverters.cs" />
<Compile Include="CompatMixins.cs" />
<Compile Include="DefaultPropertyBinding.cs" />
Expand Down
3 changes: 3 additions & 0 deletions ReactiveUI/RxApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ static RxApp()
RxApp.Register(typeof(EqualityTypeConverter), typeof(IBindingTypeConverter));
RxApp.Register(typeof(StringConverter), typeof(IBindingTypeConverter));

RxApp.Register(typeof(BindingTrackerBindingHook), typeof(IPropertyBindingHook));
RxApp.Register(typeof(BindingTrackerBindingHook), typeof(IBindingRegistry));

#if !SILVERLIGHT && !WINRT
RxApp.Register(typeof(ComponentModelTypeConverter), typeof(IBindingTypeConverter));
#endif
Expand Down

0 comments on commit 082f098

Please sign in to comment.