Browse Source
This is needed so that things like the following can be done:
<TreeView>
<TreeView.Styles>
<Style Selector="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded}"/>
</Style>
</TreeView.Styles>
<TreeView>
(At the moment we have TreeDataTemplate.IsExpanded but this isn't good
enough: it only supports setting IsExpanded on creation of the item with
no binding.)
With this commit, setters can now contain bindings, but they aren't yet
applied correctly. As part of this commit, classes related to binding
have been moved to the Perspex.Data namespace.
pull/396/head
59 changed files with 362 additions and 308 deletions
@ -1,35 +0,0 @@ |
|||
// 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 System; |
|||
using System.Reactive.Subjects; |
|||
|
|||
namespace Perspex.Markup.Xaml.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Defines a binding that can be created in XAML markup.
|
|||
/// </summary>
|
|||
public interface IXamlBinding |
|||
{ |
|||
/// <summary>
|
|||
/// Applies the binding to a property on an instance.
|
|||
/// </summary>
|
|||
/// <param name="instance">The target instance.</param>
|
|||
/// <param name="property">The target property.</param>
|
|||
void Bind(IPerspexObject instance, PerspexProperty property); |
|||
|
|||
/// <summary>
|
|||
/// Creates a subject that can be used to get and set the value of the binding.
|
|||
/// </summary>
|
|||
/// <param name="target">The target instance.</param>
|
|||
/// <param name="targetType">The type of the target property.</param>
|
|||
/// <param name="targetIsDataContext">
|
|||
/// Whether the target property is the DataContext property.
|
|||
/// </param>
|
|||
/// <returns>An <see cref="ISubject{object}"/>.</returns>
|
|||
ISubject<object> CreateSubject( |
|||
IPerspexObject target, |
|||
Type targetType, |
|||
bool targetIsDataContext = false); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
// 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 System; |
|||
|
|||
namespace Perspex.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Signifies that a binding can be assigned to a property.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Usually in markup, when a binding is set for a property that property will be bound.
|
|||
/// Applying this attribute to a property indicates that the binding should be assigned to
|
|||
/// the property rather than bound.
|
|||
/// </remarks>
|
|||
[AttributeUsage(AttributeTargets.Property)] |
|||
public sealed class AssignBindingAttribute : Attribute |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
// 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.
|
|||
|
|||
namespace Perspex.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Defines possible binding modes.
|
|||
/// </summary>
|
|||
public enum BindingMode |
|||
{ |
|||
/// <summary>
|
|||
/// Uses the default binding mode specified for the property.
|
|||
/// </summary>
|
|||
Default, |
|||
|
|||
/// <summary>
|
|||
/// Binds one way from source to target.
|
|||
/// </summary>
|
|||
OneWay, |
|||
|
|||
/// <summary>
|
|||
/// Binds two-way with the initial value coming from the target.
|
|||
/// </summary>
|
|||
TwoWay, |
|||
|
|||
/// <summary>
|
|||
/// Updates the target when the application starts or when the data context changes.
|
|||
/// </summary>
|
|||
OneTime, |
|||
|
|||
/// <summary>
|
|||
/// Binds one way from target to source.
|
|||
/// </summary>
|
|||
OneWayToSource, |
|||
} |
|||
} |
|||
@ -1,7 +1,7 @@ |
|||
// 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.
|
|||
|
|||
namespace Perspex |
|||
namespace Perspex.Data |
|||
{ |
|||
/// <summary>
|
|||
/// The priority of a binding.
|
|||
@ -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 System.Reactive.Subjects; |
|||
|
|||
namespace Perspex.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Holds a binding that can be applied to a property on an object.
|
|||
/// </summary>
|
|||
public interface IBinding |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the binding mode.
|
|||
/// </summary>
|
|||
BindingMode Mode { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the binding priority.
|
|||
/// </summary>
|
|||
BindingPriority Priority { get; } |
|||
|
|||
/// <summary>
|
|||
/// Creates a subject that can be used to get and set the value of the binding.
|
|||
/// </summary>
|
|||
/// <param name="target">The target instance.</param>
|
|||
/// <param name="targetProperty">The target property. May be null.</param>
|
|||
/// <returns>An <see cref="ISubject{Object}"/>.</returns>
|
|||
ISubject<object> CreateSubject( |
|||
IPerspexObject target, |
|||
PerspexProperty targetProperty); |
|||
} |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
// 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 System; |
|||
|
|||
namespace Perspex.Styling |
|||
{ |
|||
/// <summary>
|
|||
/// A setter for a <see cref="Style"/> whose source is an observable.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A <see cref="Setter"/> is used to set a <see cref="PerspexProperty"/> value on a
|
|||
/// <see cref="PerspexObject"/> depending on a condition.
|
|||
/// </remarks>
|
|||
public class ObservableSetter : ISetter |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ObservableSetter"/> class.
|
|||
/// </summary>
|
|||
/// <param name="property">The property to set.</param>
|
|||
/// <param name="source">An observable which produces the value for the property.</param>
|
|||
public ObservableSetter(PerspexProperty property, IObservable<object> source) |
|||
{ |
|||
Property = property; |
|||
Source = source; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the property to set.
|
|||
/// </summary>
|
|||
public PerspexProperty Property |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets an observable which produces the value for the property.
|
|||
/// </summary>
|
|||
public IObservable<object> Source |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Applies the setter to the control.
|
|||
/// </summary>
|
|||
/// <param name="style">The style that is being applied.</param>
|
|||
/// <param name="control">The control.</param>
|
|||
/// <param name="activator">An optional activator.</param>
|
|||
public void Apply(IStyle style, IStyleable control, IObservable<bool> activator) |
|||
{ |
|||
if (activator == null) |
|||
{ |
|||
control.Bind(Property, Source, BindingPriority.Style); |
|||
} |
|||
else |
|||
{ |
|||
var binding = new StyleBinding(activator, Source, style.ToString()); |
|||
control.Bind(Property, binding, BindingPriority.StyleTrigger); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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 System.Linq; |
|||
using Moq; |
|||
using Perspex.Markup.Xaml.Data; |
|||
using Perspex.Platform; |
|||
using Perspex.Styling; |
|||
using Xunit; |
|||
|
|||
namespace Perspex.Markup.Xaml.UnitTests |
|||
{ |
|||
public class StyleTests |
|||
{ |
|||
[Fact] |
|||
public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound() |
|||
{ |
|||
using (PerspexLocator.EnterScope()) |
|||
{ |
|||
PerspexLocator.CurrentMutable |
|||
.Bind<IPclPlatformWrapper>() |
|||
.ToConstant(Mock.Of<IPclPlatformWrapper>()); |
|||
|
|||
var xaml = "<Style xmlns='https://github.com/perspex'><Setter Value='{Binding}'/></Style>"; |
|||
var loader = new PerspexXamlLoader(); |
|||
var style = (Style)loader.Load(xaml); |
|||
var setter = (Setter)(style.Setters.First()); |
|||
|
|||
Assert.IsType<Binding>(setter.Value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// 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 System.Linq; |
|||
using Moq; |
|||
using Perspex.Controls.Templates; |
|||
using Perspex.Markup.Xaml.Data; |
|||
using Perspex.Markup.Xaml.Templates; |
|||
using Perspex.Platform; |
|||
using Xunit; |
|||
|
|||
namespace Perspex.Markup.Xaml.UnitTests |
|||
{ |
|||
public class TreeDataTemplateTests |
|||
{ |
|||
[Fact] |
|||
public void Binding_Should_Be_Assigned_To_ItemsSource_Instead_Of_Bound() |
|||
{ |
|||
using (PerspexLocator.EnterScope()) |
|||
{ |
|||
PerspexLocator.CurrentMutable |
|||
.Bind<IPclPlatformWrapper>() |
|||
.ToConstant(Mock.Of<IPclPlatformWrapper>()); |
|||
|
|||
var xaml = "<DataTemplates xmlns='https://github.com/perspex'><TreeDataTemplate ItemsSource='{Binding}'/></DataTemplates>"; |
|||
var loader = new PerspexXamlLoader(); |
|||
var templates = (DataTemplates)loader.Load(xaml); |
|||
var template = (TreeDataTemplate)(templates.First()); |
|||
|
|||
Assert.IsType<Binding>(template.ItemsSource); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue