TemplatedControlTests.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // -----------------------------------------------------------------------
  2. // <copyright file="TemplatedControlTests.cs" company="Steven Kirk">
  3. // Copyright 2015 MIT Licence. See licence.md for more information.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. namespace Perspex.Controls.UnitTests.Primitives
  7. {
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using Collections;
  12. using Perspex.Controls.Presenters;
  13. using Perspex.Controls.Primitives;
  14. using Perspex.Controls.Templates;
  15. using Perspex.LogicalTree;
  16. using Perspex.VisualTree;
  17. using Xunit;
  18. public class TemplatedControlTests
  19. {
  20. [Fact]
  21. public void ApplyTemplate_Should_Create_Visual_Child()
  22. {
  23. var target = new TemplatedControl
  24. {
  25. Template = new ControlTemplate(_ => new Decorator
  26. {
  27. Child = new Panel
  28. {
  29. Children = new Controls
  30. {
  31. new TextBlock(),
  32. new Border(),
  33. }
  34. }
  35. }),
  36. };
  37. target.ApplyTemplate();
  38. var types = target.GetVisualDescendents().Select(x => x.GetType()).ToList();
  39. Assert.Equal(
  40. new[]
  41. {
  42. typeof(Decorator),
  43. typeof(Panel),
  44. typeof(TextBlock),
  45. typeof(Border)
  46. },
  47. types);
  48. Assert.Empty(target.GetLogicalChildren());
  49. }
  50. [Fact]
  51. public void Templated_Children_Should_Have_TemplatedParent_Set()
  52. {
  53. var target = new TemplatedControl
  54. {
  55. Template = new ControlTemplate(_ => new Decorator
  56. {
  57. Child = new Panel
  58. {
  59. Children = new Controls
  60. {
  61. new TextBlock(),
  62. new Border(),
  63. }
  64. }
  65. }),
  66. };
  67. target.ApplyTemplate();
  68. var templatedParents = target.GetVisualDescendents()
  69. .OfType<IControl>()
  70. .Select(x => x.TemplatedParent)
  71. .ToList();
  72. Assert.Equal(4, templatedParents.Count);
  73. Assert.True(templatedParents.All(x => x == target));
  74. }
  75. [Fact]
  76. public void Templated_Child_Should_Have_Parent_Set()
  77. {
  78. var target = new TemplatedControl
  79. {
  80. Template = new ControlTemplate(_ => new Decorator())
  81. };
  82. target.ApplyTemplate();
  83. var child = (Decorator)target.GetVisualChildren().Single();
  84. Assert.Equal(target, child.Parent);
  85. Assert.Equal(target, child.GetLogicalParent());
  86. }
  87. [Fact]
  88. public void Templated_Child_Should_Have_ApplyTemplate_Called_With_Logical_Then_Visual_Parent()
  89. {
  90. var target = new TemplatedControl
  91. {
  92. Template = new ControlTemplate(_ => new ApplyTemplateTracker())
  93. };
  94. target.ApplyTemplate();
  95. var child = (ApplyTemplateTracker)target.GetVisualChildren().Single();
  96. Assert.Equal(
  97. new[]
  98. {
  99. new Tuple<IVisual, ILogical>(null, target),
  100. new Tuple<IVisual, ILogical>(target, target),
  101. },
  102. child.Invocations);
  103. }
  104. [Fact]
  105. public void Nested_TemplatedControls_Should_Be_Expanded_And_Have_Correct_TemplatedParent()
  106. {
  107. var target = new ItemsControl
  108. {
  109. Template = new ControlTemplate<ItemsControl>(ItemsControlTemplate),
  110. Items = new[] { "Foo", }
  111. };
  112. target.ApplyTemplate();
  113. var scrollViewer = target.GetVisualDescendents()
  114. .OfType<ScrollViewer>()
  115. .Single();
  116. var types = target.GetVisualDescendents()
  117. .Select(x => x.GetType())
  118. .ToList();
  119. var templatedParents = target.GetVisualDescendents()
  120. .OfType<IControl>()
  121. .Select(x => x.TemplatedParent)
  122. .ToList();
  123. Assert.Equal(
  124. new[]
  125. {
  126. typeof(Border),
  127. typeof(ScrollViewer),
  128. typeof(ScrollContentPresenter),
  129. typeof(ItemsPresenter),
  130. typeof(StackPanel),
  131. typeof(TextBlock),
  132. },
  133. types);
  134. Assert.Equal(
  135. new object[]
  136. {
  137. target,
  138. target,
  139. scrollViewer,
  140. target,
  141. target,
  142. null
  143. },
  144. templatedParents);
  145. }
  146. private static IControl ItemsControlTemplate(ItemsControl control)
  147. {
  148. return new Border
  149. {
  150. Child = new ScrollViewer
  151. {
  152. Template = new ControlTemplate<ScrollViewer>(ScrollViewerTemplate),
  153. Content = new ItemsPresenter
  154. {
  155. Name = "itemsPresenter",
  156. [~ItemsPresenter.ItemsProperty] = control[~ListBox.ItemsProperty],
  157. [~ItemsPresenter.ItemsPanelProperty] = control[~ListBox.ItemsPanelProperty],
  158. }
  159. }
  160. };
  161. }
  162. private static Control ScrollViewerTemplate(ScrollViewer control)
  163. {
  164. var result = new ScrollContentPresenter
  165. {
  166. Name = "contentPresenter",
  167. [~ScrollContentPresenter.ContentProperty] = control[~ScrollViewer.ContentProperty],
  168. };
  169. return result;
  170. }
  171. private class ApplyTemplateTracker : Control
  172. {
  173. public List<Tuple<IVisual, ILogical>> Invocations { get; } = new List<Tuple<IVisual, ILogical>>();
  174. public override void ApplyTemplate()
  175. {
  176. base.ApplyTemplate();
  177. this.Invocations.Add(Tuple.Create(this.GetVisualParent(), this.GetLogicalParent()));
  178. }
  179. }
  180. }
  181. }