diff --git a/src/Perspex.Styling/Perspex.Styling.csproj b/src/Perspex.Styling/Perspex.Styling.csproj index 8338d5a714..56b046d70e 100644 --- a/src/Perspex.Styling/Perspex.Styling.csproj +++ b/src/Perspex.Styling/Perspex.Styling.csproj @@ -48,6 +48,7 @@ + @@ -56,6 +57,7 @@ + diff --git a/src/Perspex.Styling/Styling/ISetter.cs b/src/Perspex.Styling/Styling/ISetter.cs new file mode 100644 index 0000000000..2520efca3e --- /dev/null +++ b/src/Perspex.Styling/Styling/ISetter.cs @@ -0,0 +1,18 @@ +namespace Perspex.Styling +{ + using System; + + /// + /// Represents a setter for a . + /// + public interface ISetter + { + /// + /// Applies the setter to the control. + /// + /// The style that is being applied. + /// The control. + /// An optional activator. + void Apply(IStyle style, IStyleable control, IObservable activator); + } +} \ No newline at end of file diff --git a/src/Perspex.Styling/Styling/IStyle.cs b/src/Perspex.Styling/Styling/IStyle.cs index 711c79ad28..75232c1531 100644 --- a/src/Perspex.Styling/Styling/IStyle.cs +++ b/src/Perspex.Styling/Styling/IStyle.cs @@ -6,8 +6,15 @@ namespace Perspex.Styling { + /// + /// Defines the interface for styles. + /// public interface IStyle { + /// + /// Attaches the style to a control if the style matches. + /// + /// The control to attach to. void Attach(IStyleable control); } } diff --git a/src/Perspex.Styling/Styling/ObservableSetter.cs b/src/Perspex.Styling/Styling/ObservableSetter.cs new file mode 100644 index 0000000000..7b0f504d2f --- /dev/null +++ b/src/Perspex.Styling/Styling/ObservableSetter.cs @@ -0,0 +1,68 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Styling +{ + using System; + + /// + /// A setter for a whose source is an observable. + /// + /// + /// A is used to set a value on a + /// depending on a condition. + /// + public class ObservableSetter : ISetter + { + /// + /// Initializes a new instance of the class. + /// + /// The property to set. + /// An observable which produces the value for the property. + public ObservableSetter(PerspexProperty property, IObservable source) + { + this.Property = property; + this.Source = source; + } + + /// + /// Gets or sets the property to set. + /// + public PerspexProperty Property + { + get; + set; + } + + /// + /// Gets or sets an observable which produces the value for the property. + /// + public IObservable Source + { + get; + set; + } + + /// + /// Applies the setter to the control. + /// + /// The style that is being applied. + /// The control. + /// An optional activator. + public void Apply(IStyle style, IStyleable control, IObservable activator) + { + if (activator == null) + { + control.Bind(this.Property, this.Source, BindingPriority.Style); + } + else + { + var binding = new StyleBinding(activator, this.Source, style.ToString()); + control.Bind(this.Property, binding, BindingPriority.StyleTrigger); + } + } + } +} diff --git a/src/Perspex.Styling/Styling/Setter.cs b/src/Perspex.Styling/Styling/Setter.cs index f62c20ea8f..5cd15b5951 100644 --- a/src/Perspex.Styling/Styling/Setter.cs +++ b/src/Perspex.Styling/Styling/Setter.cs @@ -15,14 +15,13 @@ namespace Perspex.Styling /// A is used to set a value on a /// depending on a condition. /// - public class Setter + public class Setter : ISetter { /// /// Initializes a new instance of the class. /// public Setter() { - } /// @@ -36,17 +35,6 @@ namespace Perspex.Styling this.Value = value; } - /// - /// Initializes a new instance of the class. - /// - /// The property to set. - /// An observable which produces the value for the property. - public Setter(PerspexProperty property, IObservable source) - { - this.Property = property; - this.Source = source; - } - /// /// Gets or sets the property to set. /// @@ -57,27 +45,31 @@ namespace Perspex.Styling } /// - /// Gets or sets an observable which produces the value for the property. + /// Gets or sets the property value. /// - /// - /// Only one of and should be set. - /// - public IObservable Source + public object Value { get; set; } /// - /// Gets or sets the property value. + /// Applies the setter to the control. /// - /// - /// Only one of and should be set. - /// - public object Value + /// The style that is being applied. + /// The control. + /// An optional activator. + public void Apply(IStyle style, IStyleable control, IObservable activator) { - get; - set; + if (activator == null) + { + control.SetValue(this.Property, this.Value, BindingPriority.Style); + } + else + { + var binding = new StyleBinding(activator, this.Value, style.ToString()); + control.Bind(this.Property, binding, BindingPriority.StyleTrigger); + } } } } diff --git a/src/Perspex.Styling/Styling/Style.cs b/src/Perspex.Styling/Styling/Style.cs index 9b0de60f60..4dcfcdefa0 100644 --- a/src/Perspex.Styling/Styling/Style.cs +++ b/src/Perspex.Styling/Styling/Style.cs @@ -8,85 +8,60 @@ namespace Perspex.Styling { using System; using System.Collections.Generic; - using System.Reactive.Linq; + /// + /// Defines a style. + /// public class Style : IStyle { + /// + /// Initializes a new instance of the class. + /// public Style() { - this.Setters = new List(); } + /// + /// Initializes a new instance of the class. + /// + /// The style selector. public Style(Func selector) - : this() { this.Selector = selector(new Selector()); } - public Selector Selector - { - get; - set; - } + /// + /// Gets or sets style's selector. + /// + public Selector Selector { get; set; } - public IEnumerable Setters - { - get; - set; - } + /// + /// Gets or sets style's setters. + /// + public IEnumerable Setters { get; set; } = new List(); + /// + /// Attaches the style to a control if the style's selector matches. + /// + /// The control to attach to. public void Attach(IStyleable control) { var description = "Style " + this.Selector.ToString(); var match = this.Selector.Match(control); - if (match.ImmediateResult.HasValue) - { - if (match.ImmediateResult == true) - { - foreach (Setter setter in this.Setters) - { - if (setter.Source != null && setter.Value != null) - { - throw new InvalidOperationException("Cannot set both Source and Value on a Setter."); - } - - if (setter.Source == null) - { - control.SetValue(setter.Property, setter.Value, BindingPriority.Style); - } - else - { - control.Bind(setter.Property, setter.Source, BindingPriority.Style); - } - } - } - } - else + if (match.ImmediateResult != false) { - foreach (Setter setter in this.Setters) + foreach (var setter in this.Setters) { - if (setter.Source != null && setter.Value != null) - { - throw new InvalidOperationException("Cannot set both Source and Value on a Setter."); - } - - StyleBinding binding; - - if (setter.Source == null) - { - binding = new StyleBinding(match.ObservableResult, setter.Value, description); - } - else - { - binding = new StyleBinding(match.ObservableResult, setter.Source, description); - } - - control.Bind(setter.Property, binding, BindingPriority.StyleTrigger); + setter.Apply(this, control, match.ObservableResult); } } } + /// + /// Returns a string representation of the style. + /// + /// A string representation of the style. public override string ToString() { return "Style: " + this.Selector.ToString(); diff --git a/tests/Perspex.Styling.UnitTests/StyleTests.cs b/tests/Perspex.Styling.UnitTests/StyleTests.cs index 8a05455352..11baa68b8d 100644 --- a/tests/Perspex.Styling.UnitTests/StyleTests.cs +++ b/tests/Perspex.Styling.UnitTests/StyleTests.cs @@ -109,7 +109,7 @@ namespace Perspex.Styling.UnitTests } [Fact] - public void Style_With_Value_And_Source_Should_Throw_Exception() + public void Style_With_ObservableSetter_Should_Update_Value() { var source = new BehaviorSubject("Foo"); @@ -117,30 +117,7 @@ namespace Perspex.Styling.UnitTests { Setters = new[] { - new Setter - { - Property = Class1.FooProperty, - Source = source, - Value = "Foo", - }, - }, - }; - - var target = new Class1(); - - Assert.Throws(() => style.Attach(target)); - } - - [Fact] - public void Style_With_Source_Should_Update_Value() - { - var source = new BehaviorSubject("Foo"); - - Style style = new Style(x => x.OfType()) - { - Setters = new[] - { - new Setter(Class1.FooProperty, source), + new ObservableSetter(Class1.FooProperty, source), }, }; @@ -149,12 +126,10 @@ namespace Perspex.Styling.UnitTests style.Attach(target); Assert.Equal("Foo", target.Foo); - source.OnNext("Bar"); - Assert.Equal("Bar", target.Foo); } [Fact] - public void Style_With_Source_Should_Update_And_Restore_Value() + public void Style_With_ObservableSetter_Should_Update_And_Restore_Value() { var source = new BehaviorSubject("Foo"); @@ -162,7 +137,7 @@ namespace Perspex.Styling.UnitTests { Setters = new[] { - new Setter(Class1.FooProperty, source), + new ObservableSetter(Class1.FooProperty, source), }, };