Browse Source

Allow binding to attached properties.

Closes #255.
pull/261/head
Steven Kirk 11 years ago
parent
commit
c7ace7b6a7
  1. 33
      src/Markup/Perspex.Markup.Xaml/Context/PerspexAttachableXamlMember.cs
  2. 30
      src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlMemberValuePlugin.cs
  3. 9
      src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs
  4. 1
      src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj

33
src/Markup/Perspex.Markup.Xaml/Context/PerspexAttachableXamlMember.cs

@ -0,0 +1,33 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Perspex.Markup.Xaml.Binding;
using OmniXaml;
using OmniXaml.Typing;
using System.Reflection;
namespace Perspex.Markup.Xaml.Context
{
public class PerspexAttachableXamlMember : AttachableXamlMember
{
public PerspexAttachableXamlMember(string name,
XamlType owner,
MethodInfo getter,
MethodInfo setter,
IXamlTypeRepository xamlTypeRepository,
ITypeFeatureProvider featureProvider)
: base(name, getter, setter, xamlTypeRepository, featureProvider)
{
}
protected override IXamlMemberValuePlugin LookupXamlMemberValueConnector()
{
return new PerspexXamlMemberValuePlugin(this);
}
public override string ToString()
{
return "Perspex Attachable XAML Member " + base.ToString();
}
}
}

30
src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlMemberValuePlugin.cs

@ -5,6 +5,7 @@ using System;
using System.Linq;
using System.Reactive.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Glass;
using OmniXaml.ObjectAssembler;
using OmniXaml.Typing;
@ -16,9 +17,9 @@ namespace Perspex.Markup.Xaml.Context
{
public class PerspexXamlMemberValuePlugin : MemberValuePlugin
{
private readonly XamlMember _xamlMember;
private readonly MutableXamlMember _xamlMember;
public PerspexXamlMemberValuePlugin(XamlMember xamlMember)
public PerspexXamlMemberValuePlugin(MutableXamlMember xamlMember)
: base(xamlMember)
{
_xamlMember = xamlMember;
@ -73,6 +74,7 @@ namespace Perspex.Markup.Xaml.Context
else
{
var perspexObject = instance as PerspexObject;
var attached = _xamlMember as PerspexAttachableXamlMember;
if (perspexObject == null)
{
@ -80,13 +82,31 @@ namespace Perspex.Markup.Xaml.Context
$"Cannot bind to an object of type '{instance.GetType()}");
}
var property = perspexObject.GetRegisteredProperties()
.FirstOrDefault(x => x.Name == _xamlMember.Name);
PerspexProperty property;
string propertyName;
if (attached == null)
{
propertyName = _xamlMember.Name;
property = perspexObject.GetRegisteredProperties()
.FirstOrDefault(x => x.Name == propertyName);
}
else
{
// Ensure the OwnerType's static ctor has been run.
RuntimeHelpers.RunClassConstructor(attached.DeclaringType.UnderlyingType.TypeHandle);
propertyName = attached.DeclaringType.UnderlyingType.Name + '.' + _xamlMember.Name;
property = perspexObject.GetRegisteredProperties()
.Where(x => x.IsAttached && x.OwnerType == attached.DeclaringType.UnderlyingType)
.FirstOrDefault(x => x.Name == _xamlMember.Name);
}
if (property == null)
{
throw new InvalidOperationException(
$"Cannot find '{_xamlMember.Name}' on '{instance.GetType()}");
$"Cannot find '{propertyName}' on '{instance.GetType()}");
}
var binding = new XamlBinding

9
src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs

@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reflection;
using OmniXaml;
using OmniXaml.Typing;
using Perspex.Markup.Xaml.Binding;
@ -22,6 +23,14 @@ namespace Perspex.Markup.Xaml.Context
return new PerspexXamlMember(name, this, TypeRepository, FeatureProvider);
}
protected override AttachableXamlMember LookupAttachableMember(string name)
{
// OmniXAML seems to require a getter and setter even though we don't use them.
var getter = UnderlyingType.GetTypeInfo().GetDeclaredMethod("Get" + name);
var setter = UnderlyingType.GetTypeInfo().GetDeclaredMethod("Set" + name);
return new PerspexAttachableXamlMember(name, this, getter, setter, TypeRepository, FeatureProvider);
}
public override string ToString()
{
return "Perspex XAML Type " + base.ToString();

1
src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj

@ -42,6 +42,7 @@
<Compile Include="Binding\TargetBindingEndpoint.cs" />
<Compile Include="Binding\XamlBinding.cs" />
<Compile Include="Binding\XamlBindingDefinition.cs" />
<Compile Include="Context\PerspexAttachableXamlMember.cs" />
<Compile Include="Converters\ColorTypeConverter.cs" />
<Compile Include="Converters\KeyGestureConverter.cs" />
<Compile Include="Converters\RelativePointTypeConverter.cs" />

Loading…
Cancel
Save