Browse Source

Get simple two-way bindings working.

pull/237/head
Steven Kirk 11 years ago
parent
commit
907505f194
  1. 9
      samples/BindingTest/App.cs
  2. 8
      samples/BindingTest/BindingTest.csproj
  3. 1
      samples/BindingTest/packages.config
  4. 3
      src/Markup/Perspex.Markup.Xaml/DataBinding/XamlBinding.cs
  5. 2
      src/Markup/Perspex.Markup/Binding/ExpressionSubject.cs
  6. 62
      src/Perspex.Base/PerspexObject.cs
  7. 2
      src/Perspex.Controls/TextBlock.cs
  8. 7
      tests/Perspex.Markup.Xaml.UnitTests/Perspex.Markup.Xaml.UnitTests.csproj
  9. 2
      tests/Perspex.Markup.Xaml.UnitTests/packages.config

9
samples/BindingTest/App.cs

@ -3,6 +3,8 @@ using Perspex;
using Perspex.Controls;
using Perspex.Diagnostics;
using Perspex.Themes.Default;
using Serilog;
using Serilog.Filters;
namespace BindingTest
{
@ -13,6 +15,13 @@ namespace BindingTest
RegisterServices();
InitializeSubsystems((int)Environment.OSVersion.Platform);
Styles = new DefaultTheme();
Log.Logger = new LoggerConfiguration()
.Filter.ByIncludingOnly(Matching.WithProperty("Area", "Property"))
.Filter.ByIncludingOnly(Matching.WithProperty<string>("Property", x => x == "Text"))
.MinimumLevel.Verbose()
.WriteTo.Trace(outputTemplate: "[{Id:X8}] [{SourceContext}] {Message}")
.CreateLogger();
}
public static void AttachDevTools(Window window)

8
samples/BindingTest/BindingTest.csproj

@ -36,6 +36,14 @@
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\..\packages\Serilog.1.5.9\lib\net45\Serilog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>

1
samples/BindingTest/packages.config

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Serilog" version="1.5.9" targetFramework="net46" />
<package id="Splat" version="1.6.2" targetFramework="net46" />
</packages>

3
src/Markup/Perspex.Markup.Xaml/DataBinding/XamlBinding.cs

@ -53,7 +53,8 @@ namespace Perspex.Markup.Xaml.DataBinding
Target.Bind(TargetProperty, observable.Select(x => x.Value));
break;
case BindingMode.TwoWay:
throw new NotImplementedException();
Target.BindTwoWay(TargetProperty, new ExpressionSubject(observable));
break;
case BindingMode.OneTime:
throw new NotImplementedException();
case BindingMode.OneWayToSource:

2
src/Markup/Perspex.Markup/Binding/ExpressionSubject.cs

@ -42,7 +42,7 @@ namespace Perspex.Markup.Binding
/// <inheritdoc/>
public IDisposable Subscribe(IObserver<object> observer)
{
return _inner.Select(x => x.Value).Distinct().Subscribe(observer);
return _inner.Select(x => x.Value).Subscribe(observer);
}
}
}

62
src/Perspex.Base/PerspexObject.cs

@ -7,6 +7,7 @@ using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reflection;
using Perspex.Reactive;
using Perspex.Utilities;
@ -492,6 +493,7 @@ namespace Perspex
throw new ArgumentException($"The property {property.Name} is readonly.");
}
LogPropertySet(property, value, priority);
property.Setter(this, value);
}
else
@ -524,14 +526,9 @@ namespace Perspex
_values.Add(property, v);
}
LogPropertySet(property, value, priority);
v.SetValue(value, (int)priority);
}
_propertyLog.Verbose(
"Set {Property} to {$Value} with priority {Priority}",
property,
value,
priority);
}
/// <summary>
@ -557,6 +554,7 @@ namespace Perspex
throw new ArgumentException($"The property {property.Name} is readonly.");
}
LogPropertySet(property, value, priority);
property.Setter(this, value);
}
else
@ -658,7 +656,7 @@ namespace Perspex
}
/// <summary>
/// Initialites a two-way bind between <see cref="PerspexProperty"/>s.
/// Initiates a two-way binding between <see cref="PerspexProperty"/>s.
/// </summary>
/// <param name="property">The property on this object.</param>
/// <param name="source">The source object.</param>
@ -676,11 +674,46 @@ namespace Perspex
PerspexProperty sourceProperty,
BindingPriority priority = BindingPriority.LocalValue)
{
_propertyLog.Verbose(
"Bound two way {Property} to {Binding} with priority {Priority}",
property,
source,
priority);
return new CompositeDisposable(
Bind(property, source.GetObservable(sourceProperty)),
source.Bind(sourceProperty, GetObservable(property)));
}
/// <summary>
/// Initiates a two-way binding between a <see cref="PerspexProperty"/> and an
/// <see cref="ISubject{Object}"/>.
/// </summary>
/// <param name="property">The property on this object.</param>
/// <param name="source">The subject to bind to.</param>
/// <param name="priority">The priority of the binding.</param>
/// <returns>
/// A disposable which can be used to terminate the binding.
/// </returns>
/// <remarks>
/// The binding is first carried out from <paramref name="source"/> to this.
/// </remarks>
public IDisposable BindTwoWay(
PerspexProperty property,
ISubject<object> source,
BindingPriority priority = BindingPriority.LocalValue)
{
_propertyLog.Verbose(
"Bound two way {Property} to {Binding} with priority {Priority}",
property,
source,
priority);
return new CompositeDisposable(
Bind(property, source),
GetObservable(property).Subscribe(source));
}
/// <summary>
/// Forces the specified property to be revalidated.
/// </summary>
@ -931,6 +964,21 @@ namespace Perspex
return string.Format("{0}.{1}", GetType().Name, property.Name);
}
/// <summary>
/// Logs a property set message.
/// </summary>
/// <param name="property">The property.</param>
/// <param name="value">The new value.</param>
/// <param name="priority">The priority.</param>
private void LogPropertySet(PerspexProperty property, object value, BindingPriority priority)
{
_propertyLog.Verbose(
"Set {Property} to {$Value} with priority {Priority}",
property,
value,
priority);
}
/// <summary>
/// Throws an exception indicating that the specified property is not registered on this
/// object.

2
src/Perspex.Controls/TextBlock.cs

@ -65,7 +65,7 @@ namespace Perspex.Controls
/// Defines the <see cref="Text"/> property.
/// </summary>
public static readonly PerspexProperty<string> TextProperty =
PerspexProperty.Register<TextBlock, string>(nameof(Text));
PerspexProperty.Register<TextBlock, string>(nameof(Text), defaultBindingMode: BindingMode.TwoWay);
/// <summary>
/// Defines the <see cref="TextAlignment"/> property.

7
tests/Perspex.Markup.Xaml.UnitTests/Perspex.Markup.Xaml.UnitTests.csproj

@ -46,13 +46,14 @@
<Reference Include="Octokit">
<HintPath>..\..\packages\Octokit.0.14.0\lib\net45\Octokit.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="Moq, Version=4.2.1409.1722, Culture=neutral, PublicKeyToken=69f491c39445e920">
<HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Splat.1.6.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="Sprache, Version=2.0.0.47, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\packages\Sprache.2.0.0.47\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid1+MonoTouch1\Sprache.dll</HintPath>
</Reference>

2
tests/Perspex.Markup.Xaml.UnitTests/packages.config

@ -6,7 +6,7 @@
<package id="Rx-Linq" version="2.2.5" targetFramework="net451" />
<package id="Rx-Main" version="2.2.5" targetFramework="net451" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net451" />
<package id="Splat" version="1.6.1" targetFramework="net451" />
<package id="Splat" version="1.6.2" targetFramework="net451" />
<package id="Sprache" version="2.0.0.47" targetFramework="net451" />
<package id="xunit" version="2.0.0" targetFramework="net451" />
<package id="xunit.abstractions" version="2.0.0" targetFramework="net451" />

Loading…
Cancel
Save