diff --git a/Perspex.UnitTests/Perspex.UnitTests.csproj b/Perspex.UnitTests/Perspex.UnitTests.csproj
index a990c1c6cb..a9d5b5368c 100644
--- a/Perspex.UnitTests/Perspex.UnitTests.csproj
+++ b/Perspex.UnitTests/Perspex.UnitTests.csproj
@@ -75,6 +75,7 @@
+
diff --git a/Perspex.UnitTests/Styling/SelectorTests_Class.cs b/Perspex.UnitTests/Styling/SelectorTests_Class.cs
index 65917c0ab4..08f1234d05 100644
--- a/Perspex.UnitTests/Styling/SelectorTests_Class.cs
+++ b/Perspex.UnitTests/Styling/SelectorTests_Class.cs
@@ -9,6 +9,8 @@ namespace Perspex.UnitTests.Styling
using System.Linq;
using System.Reactive.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Moq;
+ using Perspex.Controls;
using Perspex.Styling;
[TestClass]
@@ -40,6 +42,20 @@ namespace Perspex.UnitTests.Styling
CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray());
}
+ [TestMethod]
+ public void Class_Doesnt_Match_Control_With_TemplatedParent()
+ {
+ var control = new Control1
+ {
+ Classes = new Classes { "foo" },
+ TemplatedParent = new Mock().Object,
+ };
+
+ var target = control.Select().Class("foo");
+
+ CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray());
+ }
+
[TestMethod]
public void Class_Tracks_Additions()
{
diff --git a/Perspex.UnitTests/Styling/SelectorTests_Id.cs b/Perspex.UnitTests/Styling/SelectorTests_Id.cs
index b54ca0978f..194d7f5cbd 100644
--- a/Perspex.UnitTests/Styling/SelectorTests_Id.cs
+++ b/Perspex.UnitTests/Styling/SelectorTests_Id.cs
@@ -11,6 +11,7 @@ namespace Perspex.UnitTests.Styling
using System.Linq;
using System.Reactive.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Moq;
using Perspex.Controls;
using Perspex.Styling;
@@ -38,7 +39,7 @@ namespace Perspex.UnitTests.Styling
[TestMethod]
public void Id_Doesnt_Match_Control_With_TemplatedParent()
{
- var control = new Control1 { Id = "foo", TemplatedParent = new TemplatedControl1() };
+ var control = new Control1 { TemplatedParent = new Mock().Object };
var target = control.Select().Id("foo");
CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray());
@@ -69,13 +70,5 @@ namespace Perspex.UnitTests.Styling
public class Control1 : TestControlBase
{
}
-
- public class TemplatedControl1 : ITemplatedControl
- {
- public IEnumerable VisualChildren
- {
- get { throw new NotImplementedException(); }
- }
- }
}
}
diff --git a/Perspex.UnitTests/Styling/SelectorTests_OfType.cs b/Perspex.UnitTests/Styling/SelectorTests_OfType.cs
index e7fca49411..4936cd2e3f 100644
--- a/Perspex.UnitTests/Styling/SelectorTests_OfType.cs
+++ b/Perspex.UnitTests/Styling/SelectorTests_OfType.cs
@@ -9,6 +9,8 @@ namespace Perspex.UnitTests.Styling
using System.Linq;
using System.Reactive.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Moq;
+ using Perspex.Controls;
using Perspex.Styling;
[TestClass]
@@ -32,6 +34,15 @@ namespace Perspex.UnitTests.Styling
CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray());
}
+ [TestMethod]
+ public void OfType_Doesnt_Match_Control_With_TemplatedParent()
+ {
+ var control = new Control1 { TemplatedParent = new Mock().Object };
+ var target = control.Select().OfType();
+
+ CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray());
+ }
+
[TestMethod]
public void When_OfType_Matches_Control_Other_Selectors_Are_Subscribed()
{
diff --git a/Perspex.UnitTests/Styling/SelectorTests_Template.cs b/Perspex.UnitTests/Styling/SelectorTests_Template.cs
new file mode 100644
index 0000000000..cf51eb7e33
--- /dev/null
+++ b/Perspex.UnitTests/Styling/SelectorTests_Template.cs
@@ -0,0 +1,66 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2014 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.UnitTests.Styling
+{
+ using System.Linq;
+ using System.Reactive.Linq;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Moq;
+ using Perspex.Controls;
+ using Perspex.Styling;
+ using Match = Perspex.Styling.Match;
+
+ [TestClass]
+ public class SelectorTests_Template
+ {
+ [TestMethod]
+ public void Control_In_Template_Is_Not_Matched_Without_Template_Selector()
+ {
+ var templatedControl = new Mock();
+ var styleable = templatedControl.As();
+ this.BuildVisualTree(templatedControl);
+
+ var border = (Border)templatedControl.Object.VisualChildren.Single();
+ var selector = border.Select().OfType();
+
+ Assert.AreEqual(false, ActivatorValue(selector));
+ }
+
+ [TestMethod]
+ public void Control_In_Template_Is_Matched_With_Template_Selector()
+ {
+ var templatedControl = new Mock();
+ var styleable = templatedControl.As();
+ this.BuildVisualTree(templatedControl);
+
+ var border = (Border)templatedControl.Object.VisualChildren.Single();
+ var selector = border.Select().Template().OfType();
+
+ Assert.AreEqual(true, ActivatorValue(selector));
+ }
+
+ private static bool ActivatorValue(Match selector)
+ {
+ return selector.GetActivator().Take(1).ToEnumerable().Single();
+ }
+
+ private void BuildVisualTree(Mock templatedControl)
+ {
+ templatedControl.Setup(x => x.VisualChildren).Returns(new[]
+ {
+ new Border
+ {
+ TemplatedParent = templatedControl.Object,
+ Content = new TextBlock
+ {
+ TemplatedParent = templatedControl.Object,
+ },
+ },
+ });
+ }
+ }
+}
diff --git a/Perspex/Styling/Match.cs b/Perspex/Styling/Match.cs
index 426c174a7d..dc8304129a 100644
--- a/Perspex/Styling/Match.cs
+++ b/Perspex/Styling/Match.cs
@@ -15,6 +15,8 @@ namespace Perspex.Styling
public class Match
{
+ private IObservable observable;
+
public Match(IStyleable control)
{
this.Control = control;
@@ -41,8 +43,23 @@ namespace Perspex.Styling
public IObservable Observable
{
- get;
- set;
+ get
+ {
+ return this.observable;
+ }
+
+ set
+ {
+ if ((!InTemplate && Control.TemplatedParent == null) ||
+ (InTemplate && Control.TemplatedParent != null))
+ {
+ this.observable = value;
+ }
+ else
+ {
+ this.observable = System.Reactive.Linq.Observable.Return(false);
+ }
+ }
}
public Match Previous
diff --git a/Perspex/Styling/Selectors.cs b/Perspex/Styling/Selectors.cs
index 6fd6f09680..179e4ac8ae 100644
--- a/Perspex/Styling/Selectors.cs
+++ b/Perspex/Styling/Selectors.cs
@@ -54,5 +54,16 @@ namespace Perspex.Styling
SelectorString = typeof(T).Name,
};
}
+
+ public static Match Template(this Match match)
+ {
+ Contract.Requires(match != null);
+
+ return new Match(match)
+ {
+ InTemplate = true,
+ SelectorString = " $ ",
+ };
+ }
}
}