diff --git a/src/Perspex.Styling/Styling/IStyle.cs b/src/Perspex.Styling/Styling/IStyle.cs
index e8821349dd..4404853bf0 100644
--- a/src/Perspex.Styling/Styling/IStyle.cs
+++ b/src/Perspex.Styling/Styling/IStyle.cs
@@ -9,9 +9,12 @@ namespace Perspex.Styling
public interface IStyle
{
///
- /// Attaches the style to a control if the style matches.
+ /// Attaches the style to a control if the style's selector matches.
///
/// The control to attach to.
- void Attach(IStyleable control);
+ ///
+ /// The control that contains this style. May be null.
+ ///
+ void Attach(IStyleable control, IStyleHost container);
}
}
diff --git a/src/Perspex.Styling/Styling/Style.cs b/src/Perspex.Styling/Styling/Style.cs
index c8f4144977..f32856187e 100644
--- a/src/Perspex.Styling/Styling/Style.cs
+++ b/src/Perspex.Styling/Styling/Style.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Reactive.Linq;
namespace Perspex.Styling
{
@@ -41,16 +42,29 @@ namespace Perspex.Styling
/// Attaches the style to a control if the style's selector matches.
///
/// The control to attach to.
- public void Attach(IStyleable control)
+ ///
+ /// The control that contains this style. May be null.
+ ///
+ public void Attach(IStyleable control, IStyleHost container)
{
- var description = "Style " + Selector.ToString();
- var match = Selector.Match(control);
+ if (Selector != null)
+ {
+ var description = "Style " + Selector.ToString();
+ var match = Selector.Match(control);
- if (match.ImmediateResult != false)
+ if (match.ImmediateResult != false)
+ {
+ foreach (var setter in Setters)
+ {
+ setter.Apply(this, control, match.ObservableResult);
+ }
+ }
+ }
+ else if (control == container)
{
foreach (var setter in Setters)
{
- setter.Apply(this, control, match.ObservableResult);
+ setter.Apply(this, control, null);
}
}
}
@@ -61,7 +75,14 @@ namespace Perspex.Styling
/// A string representation of the style.
public override string ToString()
{
- return "Style: " + Selector.ToString();
+ if (Selector != null)
+ {
+ return "Style: " + Selector.ToString();
+ }
+ else
+ {
+ return "Style";
+ }
}
}
}
diff --git a/src/Perspex.Styling/Styling/Styler.cs b/src/Perspex.Styling/Styling/Styler.cs
index c129b90908..67f8bc537f 100644
--- a/src/Perspex.Styling/Styling/Styler.cs
+++ b/src/Perspex.Styling/Styling/Styler.cs
@@ -21,7 +21,7 @@ namespace Perspex.Styling
if (global != null)
{
- global.Styles.Attach(control);
+ global.Styles.Attach(control, null);
}
if (styleContainer != null)
@@ -50,7 +50,7 @@ namespace Perspex.Styling
}
}
- container.Styles.Attach(control);
+ container.Styles.Attach(control, container);
}
private IStyleHost GetParentContainer(IStyleHost container)
diff --git a/src/Perspex.Styling/Styling/Styles.cs b/src/Perspex.Styling/Styling/Styles.cs
index 2ebf858cd6..877235a337 100644
--- a/src/Perspex.Styling/Styling/Styles.cs
+++ b/src/Perspex.Styling/Styling/Styles.cs
@@ -5,13 +5,23 @@ using Perspex.Collections;
namespace Perspex.Styling
{
+ ///
+ /// A style that consists of a number of child styles.
+ ///
public class Styles : PerspexList, IStyle
{
- public void Attach(IStyleable control)
+ ///
+ /// Attaches the style to a control if the style's selector matches.
+ ///
+ /// The control to attach to.
+ ///
+ /// The control that contains this style. May be null.
+ ///
+ public void Attach(IStyleable control, IStyleHost container)
{
foreach (IStyle style in this)
{
- style.Attach(control);
+ style.Attach(control, container);
}
}
}
diff --git a/tests/Perspex.Styling.UnitTests/StyleTests.cs b/tests/Perspex.Styling.UnitTests/StyleTests.cs
index 8ab7c786ab..cda975b597 100644
--- a/tests/Perspex.Styling.UnitTests/StyleTests.cs
+++ b/tests/Perspex.Styling.UnitTests/StyleTests.cs
@@ -24,7 +24,7 @@ namespace Perspex.Styling.UnitTests
var target = new Class1();
- style.Attach(target);
+ style.Attach(target, null);
Assert.Equal("Foo", target.Foo);
}
@@ -42,7 +42,7 @@ namespace Perspex.Styling.UnitTests
var target = new Class1();
- style.Attach(target);
+ style.Attach(target, null);
Assert.Equal("foodefault", target.Foo);
target.Classes.Add("foo");
Assert.Equal("Foo", target.Foo);
@@ -50,6 +50,43 @@ namespace Perspex.Styling.UnitTests
Assert.Equal("foodefault", target.Foo);
}
+ [Fact]
+ public void Style_With_No_Selector_Should_Apply_To_Containing_Control()
+ {
+ Style style = new Style
+ {
+ Setters = new[]
+ {
+ new Setter(Class1.FooProperty, "Foo"),
+ },
+ };
+
+ var target = new Class1();
+
+ style.Attach(target, target);
+
+ Assert.Equal("Foo", target.Foo);
+ }
+
+ [Fact]
+ public void Style_With_No_Selector_Should_Not_Apply_To_Other_Control()
+ {
+ Style style = new Style
+ {
+ Setters = new[]
+ {
+ new Setter(Class1.FooProperty, "Foo"),
+ },
+ };
+
+ var target = new Class1();
+ var other = new Class1();
+
+ style.Attach(target, other);
+
+ Assert.Equal("foodefault", target.Foo);
+ }
+
[Fact]
public void LocalValue_Should_Override_Style()
{
@@ -66,7 +103,7 @@ namespace Perspex.Styling.UnitTests
Foo = "Original",
};
- style.Attach(target);
+ style.Attach(target, null);
Assert.Equal("Original", target.Foo);
}
@@ -97,7 +134,7 @@ namespace Perspex.Styling.UnitTests
List values = new List();
target.GetObservable(Class1.FooProperty).Subscribe(x => values.Add(x));
- styles.Attach(target);
+ styles.Attach(target, null);
target.Classes.Add("foo");
target.Classes.Remove("foo");
@@ -119,7 +156,7 @@ namespace Perspex.Styling.UnitTests
var target = new Class1();
- style.Attach(target);
+ style.Attach(target, null);
Assert.Equal("Foo", target.Foo);
}
@@ -139,7 +176,7 @@ namespace Perspex.Styling.UnitTests
var target = new Class1();
- style.Attach(target);
+ style.Attach(target, null);
Assert.Equal("foodefault", target.Foo);
target.Classes.Add("foo");