ContentPresenterTests_InTemplate.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System.Linq;
  4. using Avalonia.Controls.Presenters;
  5. using Avalonia.Controls.Templates;
  6. using Avalonia.LogicalTree;
  7. using Avalonia.UnitTests;
  8. using Avalonia.VisualTree;
  9. using Moq;
  10. using Xunit;
  11. namespace Avalonia.Controls.UnitTests.Presenters
  12. {
  13. /// <summary>
  14. /// Tests for ContentControls that are hosted in a control template.
  15. /// </summary>
  16. public class ContentPresenterTests_InTemplate
  17. {
  18. [Fact]
  19. public void Should_Register_With_Host_When_TemplatedParent_Set()
  20. {
  21. var host = new Mock<IContentPresenterHost>();
  22. var target = new ContentPresenter();
  23. target.SetValue(Control.TemplatedParentProperty, host.Object);
  24. host.Verify(x => x.RegisterContentPresenter(target));
  25. }
  26. [Fact]
  27. public void Setting_Content_To_Control_Should_Set_Child()
  28. {
  29. var (target, _) = CreateTarget();
  30. var child = new Border();
  31. target.Content = child;
  32. Assert.Equal(child, target.Child);
  33. }
  34. [Fact]
  35. public void Setting_Content_To_Control_Should_Update_Logical_Tree()
  36. {
  37. var (target, parent) = CreateTarget();
  38. var child = new Border();
  39. target.Content = child;
  40. Assert.Equal(parent, child.GetLogicalParent());
  41. Assert.Equal(new[] { child }, parent.GetLogicalChildren());
  42. }
  43. [Fact]
  44. public void Setting_Content_To_Control_Should_Update_Visual_Tree()
  45. {
  46. var (target, _) = CreateTarget();
  47. var child = new Border();
  48. target.Content = child;
  49. Assert.Equal(target, child.GetVisualParent());
  50. Assert.Equal(new[] { child }, target.GetVisualChildren());
  51. }
  52. [Fact]
  53. public void Setting_Content_To_String_Should_Create_TextBlock()
  54. {
  55. var (target, _) = CreateTarget();
  56. target.Content = "Foo";
  57. Assert.IsType<TextBlock>(target.Child);
  58. Assert.Equal("Foo", ((TextBlock)target.Child).Text);
  59. }
  60. [Fact]
  61. public void Setting_Content_To_String_Should_Update_Logical_Tree()
  62. {
  63. var (target, parent) = CreateTarget();
  64. target.Content = "Foo";
  65. var child = target.Child;
  66. Assert.Equal(parent, child.GetLogicalParent());
  67. Assert.Equal(new[] { child }, parent.GetLogicalChildren());
  68. }
  69. [Fact]
  70. public void Setting_Content_To_String_Should_Update_Visual_Tree()
  71. {
  72. var (target, _) = CreateTarget();
  73. target.Content = "Foo";
  74. var child = target.Child;
  75. Assert.Equal(target, child.GetVisualParent());
  76. Assert.Equal(new[] { child }, target.GetVisualChildren());
  77. }
  78. [Fact]
  79. public void Clearing_Control_Content_Should_Update_Logical_Tree()
  80. {
  81. var (target, _) = CreateTarget();
  82. var child = new Border();
  83. target.Content = child;
  84. target.Content = null;
  85. Assert.Equal(null, child.GetLogicalParent());
  86. Assert.Empty(target.GetLogicalChildren());
  87. }
  88. [Fact]
  89. public void Clearing_Control_Content_Should_Update_Visual_Tree()
  90. {
  91. var (target, _) = CreateTarget();
  92. var child = new Border();
  93. target.Content = child;
  94. target.Content = null;
  95. Assert.Equal(null, child.GetVisualParent());
  96. Assert.Empty(target.GetVisualChildren());
  97. }
  98. [Fact]
  99. public void Control_Content_Should_Not_Be_NameScope()
  100. {
  101. var (target, _) = CreateTarget();
  102. target.Content = new TextBlock();
  103. Assert.IsType<TextBlock>(target.Child);
  104. Assert.Null(NameScope.GetNameScope((Control)target.Child));
  105. }
  106. [Fact]
  107. public void DataTemplate_Created_Control_Should_Be_NameScope()
  108. {
  109. var (target, _) = CreateTarget();
  110. target.Content = "Foo";
  111. Assert.IsType<TextBlock>(target.Child);
  112. Assert.NotNull(NameScope.GetNameScope((Control)target.Child));
  113. }
  114. [Fact]
  115. public void Assigning_Control_To_Content_Should_Not_Set_DataContext()
  116. {
  117. var (target, _) = CreateTarget();
  118. target.Content = new Border();
  119. Assert.False(target.IsSet(Control.DataContextProperty));
  120. }
  121. [Fact]
  122. public void Assigning_NonControl_To_Content_Should_Set_DataContext_On_UpdateChild()
  123. {
  124. var (target, _) = CreateTarget();
  125. target.Content = "foo";
  126. Assert.Equal("foo", target.DataContext);
  127. }
  128. [Fact]
  129. public void Should_Use_ContentTemplate_If_Specified()
  130. {
  131. var (target, _) = CreateTarget();
  132. target.ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas());
  133. target.Content = "Foo";
  134. Assert.IsType<Canvas>(target.Child);
  135. }
  136. [Fact]
  137. public void Should_Update_If_ContentTemplate_Changed()
  138. {
  139. var (target, _) = CreateTarget();
  140. target.Content = "Foo";
  141. Assert.IsType<TextBlock>(target.Child);
  142. target.ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas());
  143. Assert.IsType<Canvas>(target.Child);
  144. target.ContentTemplate = null;
  145. Assert.IsType<TextBlock>(target.Child);
  146. }
  147. [Fact]
  148. public void Assigning_Control_To_Content_After_NonControl_Should_Clear_DataContext()
  149. {
  150. var (target, _) = CreateTarget();
  151. target.Content = "foo";
  152. Assert.True(target.IsSet(Control.DataContextProperty));
  153. target.Content = new Border();
  154. Assert.False(target.IsSet(Control.DataContextProperty));
  155. }
  156. [Fact]
  157. public void Recycles_DataTemplate()
  158. {
  159. var (target, _) = CreateTarget();
  160. target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), true));
  161. target.Content = "foo";
  162. var control = target.Child;
  163. Assert.IsType<Border>(control);
  164. target.Content = "bar";
  165. Assert.Same(control, target.Child);
  166. }
  167. [Fact]
  168. public void Detects_DataTemplate_Doesnt_Match_And_Doesnt_Recycle()
  169. {
  170. var (target, _) = CreateTarget();
  171. target.DataTemplates.Add(new FuncDataTemplate<string>(x => x == "foo", _ => new Border(), true));
  172. target.Content = "foo";
  173. var control = target.Child;
  174. Assert.IsType<Border>(control);
  175. target.Content = "bar";
  176. Assert.IsType<TextBlock>(target.Child);
  177. }
  178. [Fact]
  179. public void Detects_DataTemplate_Doesnt_Support_Recycling()
  180. {
  181. var (target, _) = CreateTarget();
  182. target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), false));
  183. target.Content = "foo";
  184. var control = target.Child;
  185. Assert.IsType<Border>(control);
  186. target.Content = "bar";
  187. Assert.NotSame(control, target.Child);
  188. }
  189. [Fact]
  190. public void Reevaluates_DataTemplates_When_Recycling()
  191. {
  192. var (target, _) = CreateTarget();
  193. target.DataTemplates.Add(new FuncDataTemplate<string>(x => x == "bar", _ => new Canvas(), true));
  194. target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), true));
  195. target.Content = "foo";
  196. var control = target.Child;
  197. Assert.IsType<Border>(control);
  198. target.Content = "bar";
  199. Assert.IsType<Canvas>(target.Child);
  200. }
  201. (ContentPresenter presenter, ContentControl templatedParent) CreateTarget()
  202. {
  203. var templatedParent = new ContentControl
  204. {
  205. Template = new FuncControlTemplate<ContentControl>(x =>
  206. new ContentPresenter
  207. {
  208. Name = "PART_ContentPresenter",
  209. }),
  210. };
  211. var root = new TestRoot { Child = templatedParent };
  212. templatedParent.ApplyTemplate();
  213. return ((ContentPresenter)templatedParent.Presenter, templatedParent);
  214. }
  215. private class TestContentControl : ContentControl
  216. {
  217. public IControl Child { get; set; }
  218. }
  219. }
  220. }