1
0

SelectingItemsControlTests_SelectedValue.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Avalonia.Controls.Presenters;
  7. using Avalonia.Controls.Primitives;
  8. using Avalonia.Controls.Templates;
  9. using Avalonia.Data;
  10. using Avalonia.Styling;
  11. using Avalonia.UnitTests;
  12. using Xunit;
  13. namespace Avalonia.Controls.UnitTests.Primitives
  14. {
  15. public class SelectingItemsControlTests_SelectedValue : ScopedTestBase
  16. {
  17. [Fact]
  18. public void Setting_SelectedItem_Sets_SelectedValue()
  19. {
  20. var items = TestClass.GetItems();
  21. var sic = new SelectingItemsControl
  22. {
  23. ItemsSource = items,
  24. SelectedValueBinding = new Binding("Name"),
  25. Template = Template()
  26. };
  27. sic.SelectedItem = items[1];
  28. Assert.Equal(items[1].Name, sic.SelectedValue);
  29. }
  30. [Fact]
  31. public void Setting_SelectedIndex_Sets_SelectedValue()
  32. {
  33. var items = TestClass.GetItems();
  34. var sic = new SelectingItemsControl
  35. {
  36. ItemsSource = items,
  37. SelectedValueBinding = new Binding("Name"),
  38. Template = Template()
  39. };
  40. sic.SelectedIndex = 1;
  41. Assert.Equal(items[1].Name, sic.SelectedValue);
  42. }
  43. [Fact]
  44. public void Setting_SelectedItems_Sets_SelectedValue()
  45. {
  46. var items = TestClass.GetItems();
  47. var sic = new ListBox
  48. {
  49. ItemsSource = items,
  50. SelectedValueBinding = new Binding("Name"),
  51. Template = Template()
  52. };
  53. sic.SelectedItems = new List<TestClass>
  54. {
  55. items[2],
  56. items[4],
  57. items[5]
  58. };
  59. // When interacting, SelectedItem is the first item in the SelectedItems collection
  60. // But when set here, it's the last
  61. Assert.Equal(items[5].Name, sic.SelectedValue);
  62. }
  63. [Fact]
  64. public void Setting_SelectedValue_Sets_SelectedIndex()
  65. {
  66. using (UnitTestApplication.Start(TestServices.StyledWindow))
  67. {
  68. var items = TestClass.GetItems();
  69. var sic = new SelectingItemsControl
  70. {
  71. ItemsSource = items,
  72. SelectedValueBinding = new Binding("Name"),
  73. Template = Template()
  74. };
  75. Prepare(sic);
  76. sic.SelectedValue = items[2].Name;
  77. Assert.Equal(2, sic.SelectedIndex);
  78. }
  79. }
  80. [Fact]
  81. public void Setting_SelectedValue_Sets_SelectedItem()
  82. {
  83. using (UnitTestApplication.Start(TestServices.StyledWindow))
  84. {
  85. var items = TestClass.GetItems();
  86. var sic = new SelectingItemsControl
  87. {
  88. ItemsSource = items,
  89. SelectedValueBinding = new Binding("Name"),
  90. Template = Template()
  91. };
  92. Prepare(sic);
  93. sic.SelectedValue = "Item2";
  94. Assert.Equal(items[2], sic.SelectedItem);
  95. }
  96. }
  97. [Fact]
  98. public void Changing_SelectedValueBinding_Updates_SelectedValue()
  99. {
  100. using (UnitTestApplication.Start(TestServices.StyledWindow))
  101. {
  102. var items = TestClass.GetItems();
  103. var sic = new SelectingItemsControl
  104. {
  105. ItemsSource = items,
  106. SelectedValueBinding = new Binding("Name"),
  107. Template = Template()
  108. };
  109. sic.SelectedValue = "Item2";
  110. sic.SelectedValueBinding = new Binding("AltProperty");
  111. // Ensure SelectedItem didn't change
  112. Assert.Equal(items[2], sic.SelectedItem);
  113. Assert.Equal("Alt2", sic.SelectedValue);
  114. }
  115. }
  116. [Fact]
  117. public void SelectedValue_With_Null_SelectedValueBinding_Is_Item()
  118. {
  119. var items = TestClass.GetItems();
  120. var sic = new SelectingItemsControl
  121. {
  122. ItemsSource = items,
  123. Template = Template()
  124. };
  125. sic.SelectedIndex = 1;
  126. Assert.Equal(items[1], sic.SelectedValue);
  127. }
  128. [Fact]
  129. public void Setting_SelectedValue_Before_Initialize_Should_Retain_Selection()
  130. {
  131. var items = TestClass.GetItems();
  132. var sic = new SelectingItemsControl
  133. {
  134. ItemsSource = items,
  135. Template = Template(),
  136. SelectedValueBinding = new Binding("Name"),
  137. SelectedValue = "Item2"
  138. };
  139. sic.BeginInit();
  140. sic.EndInit();
  141. Assert.Equal(items[2].Name, sic.SelectedValue);
  142. }
  143. [Fact]
  144. public void Setting_SelectedValue_To_Non_Existent_Item_Without_ItemsSource_Should_Keep_Selection_Until_ItemsSource_Is_Set()
  145. {
  146. var target = new SelectingItemsControl
  147. {
  148. Template = Template(),
  149. SelectedValueBinding = new Binding("Name")
  150. };
  151. target.ApplyTemplate();
  152. target.SelectedValue = "Item2";
  153. Assert.Equal(-1, target.SelectedIndex);
  154. Assert.Null(target.SelectedItem);
  155. Assert.Same("Item2", target.SelectedValue);
  156. target.ItemsSource = Array.Empty<TestClass>();
  157. Assert.Equal(-1, target.SelectedIndex);
  158. Assert.Null(target.SelectedItem);
  159. Assert.Null(target.SelectedValue);
  160. }
  161. [Fact]
  162. public void Setting_SelectedValue_Without_ItemsSource_Should_Keep_Selection_If_Item_Exists_When_ItemsSource_IsSet()
  163. {
  164. var target = new SelectingItemsControl
  165. {
  166. Template = Template(),
  167. SelectedValueBinding = new Binding("Name")
  168. };
  169. target.ApplyTemplate();
  170. target.SelectedValue = "Item2";
  171. Assert.Equal(-1, target.SelectedIndex);
  172. Assert.Null(target.SelectedItem);
  173. Assert.Same("Item2", target.SelectedValue);
  174. var items = TestClass.GetItems();
  175. target.ItemsSource = items;
  176. Assert.Equal(2, target.SelectedIndex);
  177. Assert.Same(items[2], target.SelectedItem);
  178. Assert.Equal("Item2", target.SelectedValue);
  179. }
  180. [Fact]
  181. public void Setting_SelectedValue_During_Initialize_Should_Take_Priority_Over_Previous_Value()
  182. {
  183. var items = TestClass.GetItems();
  184. var sic = new SelectingItemsControl
  185. {
  186. ItemsSource = items,
  187. Template = Template(),
  188. SelectedValueBinding = new Binding("Name"),
  189. SelectedValue = "Item2"
  190. };
  191. sic.BeginInit();
  192. sic.SelectedValue = "Item1";
  193. sic.EndInit();
  194. Assert.Equal(items[1].Name, sic.SelectedValue);
  195. }
  196. [Fact]
  197. public void Changing_Items_Should_Clear_SelectedValue()
  198. {
  199. using (UnitTestApplication.Start(TestServices.StyledWindow))
  200. {
  201. var items = TestClass.GetItems();
  202. var sic = new SelectingItemsControl
  203. {
  204. ItemsSource = items,
  205. Template = Template(),
  206. SelectedValueBinding = new Binding("Name"),
  207. SelectedValue = "Item2"
  208. };
  209. Prepare(sic);
  210. sic.ItemsSource = new List<TestClass>
  211. {
  212. new TestClass("NewItem", string.Empty)
  213. };
  214. Assert.Equal(null, sic.SelectedValue);
  215. }
  216. }
  217. [Fact]
  218. public void Setting_SelectedValue_Should_Raise_SelectionChanged_Event()
  219. {
  220. // Unlike SelectedIndex/SelectedItem tests, we need the ItemsControl to
  221. // initialize so that SelectedValue can actually be looked up
  222. using (UnitTestApplication.Start(TestServices.StyledWindow))
  223. {
  224. var items = TestClass.GetItems();
  225. var sic = new SelectingItemsControl
  226. {
  227. ItemsSource = items,
  228. Template = Template(),
  229. SelectedValueBinding = new Binding("Name"),
  230. };
  231. Prepare(sic);
  232. var called = false;
  233. sic.SelectionChanged += (s, e) =>
  234. {
  235. Assert.Same(items[2], e.AddedItems.Cast<object>().Single());
  236. Assert.Empty(e.RemovedItems);
  237. called = true;
  238. };
  239. sic.SelectedValue = "Item2";
  240. Assert.True(called);
  241. }
  242. }
  243. [Fact]
  244. public void Clearing_SelectedValue_Should_Raise_SelectionChanged_Event()
  245. {
  246. var items = TestClass.GetItems();
  247. var sic = new SelectingItemsControl
  248. {
  249. ItemsSource = items,
  250. Template = Template(),
  251. SelectedValueBinding = new Binding("Name"),
  252. SelectedValue = "Item2"
  253. };
  254. var called = false;
  255. sic.SelectionChanged += (s, e) =>
  256. {
  257. Assert.Same(items[2], e.RemovedItems.Cast<object>().Single());
  258. Assert.Empty(e.AddedItems);
  259. called = true;
  260. };
  261. sic.SelectedValue = null;
  262. Assert.True(called);
  263. }
  264. [Fact]
  265. public void Handles_Null_SelectedItem_When_SelectedValueBinding_Assigned()
  266. {
  267. // Issue #11220
  268. var items = new object[] { null };
  269. var sic = new SelectingItemsControl
  270. {
  271. ItemsSource = items,
  272. SelectedIndex = 1,
  273. SelectedValueBinding = new Binding("Name"),
  274. Template = Template()
  275. };
  276. Assert.Null(sic.SelectedValue);
  277. }
  278. private static FuncControlTemplate Template()
  279. {
  280. return new FuncControlTemplate<SelectingItemsControl>((control, scope) =>
  281. new ItemsPresenter
  282. {
  283. Name = "itemsPresenter",
  284. [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
  285. }.RegisterInNameScope(scope));
  286. }
  287. private static void Prepare(SelectingItemsControl target)
  288. {
  289. var root = new TestRoot
  290. {
  291. Child = target,
  292. Width = 100,
  293. Height = 100,
  294. Styles =
  295. {
  296. new Style(x => x.Is<SelectingItemsControl>())
  297. {
  298. Setters =
  299. {
  300. new Setter(ListBox.TemplateProperty, Template()),
  301. },
  302. },
  303. },
  304. };
  305. root.LayoutManager.ExecuteInitialLayoutPass();
  306. }
  307. }
  308. internal class TestClass
  309. {
  310. public TestClass(string name, string alt)
  311. {
  312. Name = name;
  313. AltProperty = alt;
  314. }
  315. public string Name { get; set; }
  316. public string AltProperty { get; set; }
  317. public static List<TestClass> GetItems()
  318. {
  319. return new List<TestClass>
  320. {
  321. new TestClass(null, null),
  322. new TestClass("Item1", "Alt1"),
  323. new TestClass("Item2", "Alt2"),
  324. new TestClass("Item3", "Alt3"),
  325. new TestClass("Item4", "Alt4"),
  326. new TestClass("Item5", "Alt5"),
  327. };
  328. }
  329. }
  330. }