BindingTests_RelativeSource.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reactive.Subjects;
  4. using Avalonia.Controls;
  5. using Avalonia.Data;
  6. using Avalonia.Data.Core;
  7. using Avalonia.Markup.Parsers;
  8. using Avalonia.UnitTests;
  9. using Xunit;
  10. namespace Avalonia.Markup.UnitTests.Data
  11. {
  12. public class BindingTests_RelativeSource : ScopedTestBase
  13. {
  14. [Fact]
  15. public void Should_Bind_To_First_Ancestor()
  16. {
  17. TextBlock target;
  18. var root = new TestRoot
  19. {
  20. Child = new Decorator
  21. {
  22. Name = "decorator",
  23. Child = target = new TextBlock(),
  24. },
  25. };
  26. var binding = new Binding
  27. {
  28. Path = "Name",
  29. RelativeSource = new RelativeSource
  30. {
  31. AncestorType = typeof(Decorator),
  32. }
  33. };
  34. target.Bind(TextBox.TextProperty, binding);
  35. Assert.Equal("decorator", target.Text);
  36. }
  37. [Fact]
  38. public void Should_Bind_To_Second_Ancestor()
  39. {
  40. TextBlock target;
  41. var root = new TestRoot
  42. {
  43. Child = new Decorator
  44. {
  45. Name = "decorator1",
  46. Child = new Decorator
  47. {
  48. Name = "decorator2",
  49. Child = target = new TextBlock(),
  50. }
  51. },
  52. };
  53. var binding = new Binding
  54. {
  55. Path = "Name",
  56. RelativeSource = new RelativeSource
  57. {
  58. AncestorType = typeof(Decorator),
  59. AncestorLevel = 2,
  60. }
  61. };
  62. target.Bind(TextBox.TextProperty, binding);
  63. Assert.Equal("decorator1", target.Text);
  64. }
  65. [Fact]
  66. public void Should_Bind_To_Derived_Ancestor_Type()
  67. {
  68. TextBlock target;
  69. var root = new TestRoot
  70. {
  71. Child = new Border
  72. {
  73. Name = "border",
  74. Child = target = new TextBlock(),
  75. },
  76. };
  77. var binding = new Binding
  78. {
  79. Path = "Name",
  80. RelativeSource = new RelativeSource
  81. {
  82. AncestorType = typeof(Decorator),
  83. }
  84. };
  85. target.Bind(TextBox.TextProperty, binding);
  86. Assert.Equal("border", target.Text);
  87. }
  88. [Fact]
  89. public void Should_Produce_Null_If_Ancestor_Not_Found()
  90. {
  91. TextBlock target;
  92. var root = new TestRoot
  93. {
  94. Child = new Decorator
  95. {
  96. Name = "decorator",
  97. Child = target = new TextBlock(),
  98. },
  99. };
  100. var binding = new Binding
  101. {
  102. Path = "Name",
  103. RelativeSource = new RelativeSource
  104. {
  105. AncestorType = typeof(Decorator),
  106. AncestorLevel = 2,
  107. }
  108. };
  109. target.Bind(TextBox.TextProperty, binding);
  110. Assert.Null(target.Text);
  111. }
  112. [Fact]
  113. public void Should_Update_When_Detached_And_Attached_To_Visual_Tree()
  114. {
  115. TextBlock target;
  116. Decorator decorator1;
  117. Decorator decorator2;
  118. var root1 = new TestRoot
  119. {
  120. Child = decorator1 = new Decorator
  121. {
  122. Name = "decorator1",
  123. Child = target = new TextBlock(),
  124. },
  125. };
  126. var root2 = new TestRoot
  127. {
  128. Child = decorator2 = new Decorator
  129. {
  130. Name = "decorator2",
  131. },
  132. };
  133. var binding = new Binding
  134. {
  135. Path = "Name",
  136. RelativeSource = new RelativeSource
  137. {
  138. AncestorType = typeof(Decorator),
  139. }
  140. };
  141. target.Bind(TextBox.TextProperty, binding);
  142. Assert.Equal("decorator1", target.Text);
  143. decorator1.Child = null;
  144. Assert.Null(target.Text);
  145. decorator2.Child = target;
  146. Assert.Equal("decorator2", target.Text);
  147. }
  148. [Fact]
  149. public void Should_Update_When_Detached_And_Attached_To_Visual_Tree_With_BindingPath()
  150. {
  151. TextBlock target;
  152. Decorator decorator1;
  153. Decorator decorator2;
  154. var viewModel = new { Value = "Foo" };
  155. var root1 = new TestRoot
  156. {
  157. Child = decorator1 = new Decorator
  158. {
  159. Name = "decorator1",
  160. Child = target = new TextBlock(),
  161. },
  162. DataContext = viewModel
  163. };
  164. var root2 = new TestRoot
  165. {
  166. Child = decorator2 = new Decorator
  167. {
  168. Name = "decorator2",
  169. },
  170. DataContext = viewModel
  171. };
  172. var binding = new Binding
  173. {
  174. Path = "DataContext.Value",
  175. RelativeSource = new RelativeSource
  176. {
  177. AncestorType = typeof(Decorator),
  178. }
  179. };
  180. target.Bind(TextBox.TextProperty, binding);
  181. Assert.Equal("Foo", target.Text);
  182. decorator1.Child = null;
  183. Assert.Null(target.Text);
  184. decorator2.Child = target;
  185. Assert.Equal("Foo", target.Text);
  186. }
  187. [Fact]
  188. public void Should_Update_When_Detached_And_Attached_To_Visual_Tree_With_ComplexBindingPath()
  189. {
  190. TextBlock target;
  191. Decorator decorator1;
  192. Decorator decorator2;
  193. var vm = new { Foo = new { Value = "Foo" } };
  194. var root1 = new TestRoot
  195. {
  196. Child = decorator1 = new Decorator
  197. {
  198. Name = "decorator1",
  199. Child = target = new TextBlock(),
  200. },
  201. DataContext = vm
  202. };
  203. var root2 = new TestRoot
  204. {
  205. Child = decorator2 = new Decorator
  206. {
  207. Name = "decorator2",
  208. },
  209. DataContext = vm
  210. };
  211. var binding = new Binding
  212. {
  213. Path = "DataContext.Foo.Value",
  214. RelativeSource = new RelativeSource
  215. {
  216. AncestorType = typeof(Decorator),
  217. }
  218. };
  219. target.Bind(TextBox.TextProperty, binding);
  220. Assert.Equal("Foo", target.Text);
  221. decorator1.Child = null;
  222. Assert.Null(target.Text);
  223. decorator2.Child = target;
  224. Assert.Equal("Foo", target.Text);
  225. }
  226. }
  227. }