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 = " $ ", + }; + } } }