ItemsControlTests.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.Collections.Specialized;
  4. using System.Linq;
  5. using Avalonia.Collections;
  6. using Avalonia.Controls.Presenters;
  7. using Avalonia.Controls.Templates;
  8. using Avalonia.Data;
  9. using Avalonia.Input;
  10. using Avalonia.LogicalTree;
  11. using Avalonia.Styling;
  12. using Avalonia.UnitTests;
  13. using Xunit;
  14. namespace Avalonia.Controls.UnitTests
  15. {
  16. public class ItemsControlTests
  17. {
  18. [Fact]
  19. public void Should_Use_ItemTemplate_To_Create_Control()
  20. {
  21. var target = new ItemsControl
  22. {
  23. Template = GetTemplate(),
  24. ItemTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
  25. };
  26. target.Items = new[] { "Foo" };
  27. target.ApplyTemplate();
  28. target.Presenter.ApplyTemplate();
  29. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  30. container.UpdateChild();
  31. Assert.IsType<Canvas>(container.Child);
  32. }
  33. [Fact]
  34. public void ItemTemplate_Can_Be_Changed()
  35. {
  36. var target = new ItemsControl
  37. {
  38. Template = GetTemplate(),
  39. ItemTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
  40. };
  41. target.Items = new[] { "Foo" };
  42. target.ApplyTemplate();
  43. target.Presenter.ApplyTemplate();
  44. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  45. container.UpdateChild();
  46. Assert.IsType<Canvas>(container.Child);
  47. target.ItemTemplate = new FuncDataTemplate<string>((_, __) => new Border());
  48. container = (ContentPresenter)target.Presenter.Panel.Children[0];
  49. container.UpdateChild();
  50. Assert.IsType<Border>(container.Child);
  51. }
  52. [Fact]
  53. public void Panel_Should_Have_TemplatedParent_Set_To_ItemsControl()
  54. {
  55. var target = new ItemsControl();
  56. target.Template = GetTemplate();
  57. target.Items = new[] { "Foo" };
  58. target.ApplyTemplate();
  59. target.Presenter.ApplyTemplate();
  60. Assert.Equal(target, target.Presenter.Panel.TemplatedParent);
  61. }
  62. [Fact]
  63. public void Container_Should_Have_TemplatedParent_Set_To_Null()
  64. {
  65. var target = new ItemsControl();
  66. target.Template = GetTemplate();
  67. target.Items = new[] { "Foo" };
  68. target.ApplyTemplate();
  69. target.Presenter.ApplyTemplate();
  70. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  71. Assert.Null(container.TemplatedParent);
  72. }
  73. [Fact]
  74. public void Container_Should_Have_Theme_Set_To_ItemContainerTheme()
  75. {
  76. var theme = new ControlTheme { TargetType = typeof(ContentPresenter) };
  77. var target = new ItemsControl
  78. {
  79. ItemContainerTheme = theme,
  80. };
  81. target.Template = GetTemplate();
  82. target.Items = new[] { "Foo" };
  83. target.ApplyTemplate();
  84. target.Presenter.ApplyTemplate();
  85. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  86. Assert.Same(container.Theme, theme);
  87. }
  88. [Fact]
  89. public void Container_Should_Have_LogicalParent_Set_To_ItemsControl()
  90. {
  91. using (UnitTestApplication.Start(TestServices.StyledWindow))
  92. {
  93. var root = new Window();
  94. var target = new ItemsControl();
  95. root.Content = target;
  96. var templatedParent = new Button();
  97. target.SetValue(StyledElement.TemplatedParentProperty, templatedParent);
  98. target.Template = GetTemplate();
  99. target.Items = new[] { "Foo" };
  100. root.ApplyTemplate();
  101. target.ApplyTemplate();
  102. target.Presenter.ApplyTemplate();
  103. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  104. Assert.Equal(target, container.Parent);
  105. }
  106. }
  107. [Fact]
  108. public void Control_Item_Should_Be_Logical_Child_Before_ApplyTemplate()
  109. {
  110. var target = new ItemsControl();
  111. var child = new Control();
  112. target.Template = GetTemplate();
  113. target.Items = new[] { child };
  114. Assert.Equal(child.Parent, target);
  115. Assert.Equal(child.GetLogicalParent(), target);
  116. Assert.Equal(new[] { child }, target.GetLogicalChildren());
  117. }
  118. [Fact]
  119. public void Control_Item_Should_Be_Logical_Child_After_Layout()
  120. {
  121. var target = new ItemsControl
  122. {
  123. Template = GetTemplate(),
  124. };
  125. var root = new TestRoot(target);
  126. var child = new Control();
  127. target.Template = GetTemplate();
  128. target.Items = new[] { child };
  129. root.LayoutManager.ExecuteInitialLayoutPass();
  130. Assert.Equal(target, child.Parent);
  131. Assert.Equal(target, child.GetLogicalParent());
  132. Assert.Equal(new[] { child }, target.GetLogicalChildren());
  133. }
  134. [Fact]
  135. public void Added_Container_Should_Have_LogicalParent_Set_To_ItemsControl()
  136. {
  137. var item = new Border();
  138. var items = new ObservableCollection<Border>();
  139. var target = new ItemsControl
  140. {
  141. Template = GetTemplate(),
  142. Items = items,
  143. };
  144. var root = new TestRoot(true, target);
  145. root.Measure(new Size(100, 100));
  146. root.Arrange(new Rect(0, 0, 100, 100));
  147. items.Add(item);
  148. Assert.Equal(target, item.Parent);
  149. }
  150. [Fact]
  151. public void Control_Item_Should_Be_Removed_From_Logical_Children_Before_ApplyTemplate()
  152. {
  153. var target = new ItemsControl();
  154. var child = new Control();
  155. var items = new AvaloniaList<Control>(child);
  156. target.Template = GetTemplate();
  157. target.Items = items;
  158. items.RemoveAt(0);
  159. Assert.Null(child.Parent);
  160. Assert.Null(child.GetLogicalParent());
  161. Assert.Empty(target.GetLogicalChildren());
  162. }
  163. [Fact]
  164. public void Clearing_Items_Should_Clear_Child_Controls_Parent_Before_ApplyTemplate()
  165. {
  166. var target = new ItemsControl();
  167. var child = new Control();
  168. target.Template = GetTemplate();
  169. target.Items = new[] { child };
  170. target.Items = null;
  171. Assert.Null(child.Parent);
  172. Assert.Null(((ILogical)child).LogicalParent);
  173. }
  174. [Fact]
  175. public void Clearing_Items_Should_Clear_Child_Controls_Parent()
  176. {
  177. var target = new ItemsControl();
  178. var child = new Control();
  179. target.Template = GetTemplate();
  180. target.Items = new[] { child };
  181. target.ApplyTemplate();
  182. target.Items = null;
  183. Assert.Null(child.Parent);
  184. Assert.Null(((ILogical)child).LogicalParent);
  185. }
  186. [Fact]
  187. public void Adding_Control_Item_Should_Make_Control_Appear_In_LogicalChildren()
  188. {
  189. var target = new ItemsControl();
  190. var child = new Control();
  191. target.Template = GetTemplate();
  192. target.Items = new[] { child };
  193. // Should appear both before and after applying template.
  194. Assert.Equal(new ILogical[] { child }, target.GetLogicalChildren());
  195. target.ApplyTemplate();
  196. Assert.Equal(new ILogical[] { child }, target.GetLogicalChildren());
  197. }
  198. [Fact]
  199. public void Adding_String_Item_Should_Make_ContentPresenter_Appear_In_LogicalChildren()
  200. {
  201. var target = new ItemsControl();
  202. var child = new Control();
  203. target.Template = GetTemplate();
  204. target.Items = new[] { "Foo" };
  205. target.ApplyTemplate();
  206. target.Presenter.ApplyTemplate();
  207. var logical = (ILogical)target;
  208. Assert.Equal(1, logical.LogicalChildren.Count);
  209. Assert.IsType<ContentPresenter>(logical.LogicalChildren[0]);
  210. }
  211. [Fact]
  212. public void Setting_Items_To_Null_Should_Remove_LogicalChildren()
  213. {
  214. var target = new ItemsControl();
  215. var child = new Control();
  216. target.Template = GetTemplate();
  217. target.Items = new[] { "Foo" };
  218. target.ApplyTemplate();
  219. target.Presenter.ApplyTemplate();
  220. Assert.NotEmpty(target.GetLogicalChildren());
  221. target.Items = null;
  222. Assert.Equal(new ILogical[0], target.GetLogicalChildren());
  223. }
  224. [Fact]
  225. public void Setting_Items_Should_Fire_LogicalChildren_CollectionChanged()
  226. {
  227. var target = new ItemsControl();
  228. var child = new Control();
  229. var called = false;
  230. target.Template = GetTemplate();
  231. target.ApplyTemplate();
  232. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
  233. called = e.Action == NotifyCollectionChangedAction.Add;
  234. target.Items = new[] { child };
  235. Assert.True(called);
  236. }
  237. [Fact]
  238. public void Setting_Items_To_Null_Should_Fire_LogicalChildren_CollectionChanged()
  239. {
  240. var target = new ItemsControl();
  241. var child = new Control();
  242. var called = false;
  243. target.Template = GetTemplate();
  244. target.Items = new[] { child };
  245. target.ApplyTemplate();
  246. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
  247. called = e.Action == NotifyCollectionChangedAction.Remove;
  248. target.Items = null;
  249. Assert.True(called);
  250. }
  251. [Fact]
  252. public void Changing_Items_Should_Fire_LogicalChildren_CollectionChanged()
  253. {
  254. var target = new ItemsControl();
  255. var child = new Control();
  256. var called = false;
  257. target.Template = GetTemplate();
  258. target.Items = new[] { child };
  259. target.ApplyTemplate();
  260. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
  261. target.Items = new[] { "Foo" };
  262. Assert.True(called);
  263. }
  264. [Fact]
  265. public void Adding_Items_Should_Fire_LogicalChildren_CollectionChanged()
  266. {
  267. var target = new ItemsControl();
  268. var items = new AvaloniaList<string> { "Foo" };
  269. var called = false;
  270. target.Template = GetTemplate();
  271. target.Items = items;
  272. target.ApplyTemplate();
  273. target.Presenter.ApplyTemplate();
  274. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
  275. called = e.Action == NotifyCollectionChangedAction.Add;
  276. items.Add("Bar");
  277. Assert.True(called);
  278. }
  279. [Fact]
  280. public void Removing_Items_Should_Fire_LogicalChildren_CollectionChanged()
  281. {
  282. var target = new ItemsControl();
  283. var items = new AvaloniaList<string> { "Foo", "Bar" };
  284. var called = false;
  285. target.Template = GetTemplate();
  286. target.Items = items;
  287. target.ApplyTemplate();
  288. target.Presenter.ApplyTemplate();
  289. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
  290. called = e.Action == NotifyCollectionChangedAction.Remove;
  291. items.Remove("Bar");
  292. Assert.True(called);
  293. }
  294. [Fact]
  295. public void LogicalChildren_Should_Not_Change_Instance_When_Template_Changed()
  296. {
  297. var target = new ItemsControl()
  298. {
  299. Template = GetTemplate(),
  300. };
  301. var before = ((ILogical)target).LogicalChildren;
  302. target.Template = null;
  303. target.Template = GetTemplate();
  304. var after = ((ILogical)target).LogicalChildren;
  305. Assert.NotNull(before);
  306. Assert.NotNull(after);
  307. Assert.Same(before, after);
  308. }
  309. [Fact]
  310. public void Should_Clear_Containers_When_ItemsPresenter_Changes()
  311. {
  312. var target = new ItemsControl
  313. {
  314. Items = new[] { "foo", "bar" },
  315. Template = GetTemplate(),
  316. };
  317. target.ApplyTemplate();
  318. target.Presenter.ApplyTemplate();
  319. var panel = target.Presenter.Panel;
  320. Assert.Equal(2, panel.Children.Count());
  321. target.Template = GetTemplate();
  322. target.ApplyTemplate();
  323. Assert.Empty(panel.Children);
  324. }
  325. [Fact]
  326. public void Empty_Class_Should_Initially_Be_Applied()
  327. {
  328. var target = new ItemsControl()
  329. {
  330. Template = GetTemplate(),
  331. };
  332. Assert.Contains(":empty", target.Classes);
  333. }
  334. [Fact]
  335. public void Empty_Class_Should_Be_Cleared_When_Items_Added()
  336. {
  337. var target = new ItemsControl()
  338. {
  339. Template = GetTemplate(),
  340. Items = new[] { 1, 2, 3 },
  341. };
  342. Assert.DoesNotContain(":empty", target.Classes);
  343. }
  344. [Fact]
  345. public void Empty_Class_Should_Be_Set_When_Items_Not_Set()
  346. {
  347. var target = new ItemsControl()
  348. {
  349. Template = GetTemplate(),
  350. };
  351. Assert.Contains(":empty", target.Classes);
  352. }
  353. [Fact]
  354. public void Empty_Class_Should_Be_Set_When_Empty_Collection_Set()
  355. {
  356. var target = new ItemsControl()
  357. {
  358. Template = GetTemplate(),
  359. Items = new[] { 1, 2, 3 },
  360. };
  361. target.Items = new int[0];
  362. Assert.Contains(":empty", target.Classes);
  363. }
  364. [Fact]
  365. public void Item_Count_Should_Be_Set_When_Items_Added()
  366. {
  367. var target = new ItemsControl()
  368. {
  369. Template = GetTemplate(),
  370. Items = new[] { 1, 2, 3 },
  371. };
  372. Assert.Equal(3, target.ItemCount);
  373. }
  374. [Fact]
  375. public void Item_Count_Should_Be_Set_When_Items_Changed()
  376. {
  377. var items = new ObservableCollection<int>() { 1, 2, 3 };
  378. var target = new ItemsControl()
  379. {
  380. Template = GetTemplate(),
  381. Items = items,
  382. };
  383. items.Add(4);
  384. Assert.Equal(4, target.ItemCount);
  385. items.Clear();
  386. Assert.Equal(0, target.ItemCount);
  387. }
  388. [Fact]
  389. public void Empty_Class_Should_Be_Set_When_Items_Collection_Cleared()
  390. {
  391. var items = new ObservableCollection<int>() { 1, 2, 3 };
  392. var target = new ItemsControl()
  393. {
  394. Template = GetTemplate(),
  395. Items = items,
  396. };
  397. items.Clear();
  398. Assert.Contains(":empty", target.Classes);
  399. }
  400. [Fact]
  401. public void Empty_Class_Should_Not_Be_Set_When_Items_Collection_Count_Increases()
  402. {
  403. var items = new ObservableCollection<int>() { };
  404. var target = new ItemsControl()
  405. {
  406. Template = GetTemplate(),
  407. Items = items,
  408. };
  409. items.Add(1);
  410. Assert.DoesNotContain(":empty", target.Classes);
  411. }
  412. [Fact]
  413. public void Single_Item_Class_Should_Be_Set_When_Items_Collection_Count_Increases_To_One()
  414. {
  415. var items = new ObservableCollection<int>() { };
  416. var target = new ItemsControl()
  417. {
  418. Template = GetTemplate(),
  419. Items = items,
  420. };
  421. items.Add(1);
  422. Assert.Contains(":singleitem", target.Classes);
  423. }
  424. [Fact]
  425. public void Empty_Class_Should_Not_Be_Set_When_Items_Collection_Cleared()
  426. {
  427. var items = new ObservableCollection<int>() { 1, 2, 3 };
  428. var target = new ItemsControl()
  429. {
  430. Template = GetTemplate(),
  431. Items = items,
  432. };
  433. items.Clear();
  434. Assert.DoesNotContain(":singleitem", target.Classes);
  435. }
  436. [Fact]
  437. public void Single_Item_Class_Should_Not_Be_Set_When_Items_Collection_Count_Increases_Beyond_One()
  438. {
  439. var items = new ObservableCollection<int>() { 1 };
  440. var target = new ItemsControl()
  441. {
  442. Template = GetTemplate(),
  443. Items = items,
  444. };
  445. items.Add(2);
  446. Assert.DoesNotContain(":singleitem", target.Classes);
  447. }
  448. [Fact]
  449. public void DataContexts_Should_Be_Correctly_Set()
  450. {
  451. var items = new object[]
  452. {
  453. "Foo",
  454. new Item("Bar"),
  455. new TextBlock { Text = "Baz" },
  456. new ListBoxItem { Content = "Qux" },
  457. };
  458. var target = new ItemsControl
  459. {
  460. Template = GetTemplate(),
  461. DataContext = "Base",
  462. DataTemplates =
  463. {
  464. new FuncDataTemplate<Item>((x, __) => new Button { Content = x })
  465. },
  466. Items = items,
  467. };
  468. target.ApplyTemplate();
  469. target.Presenter.ApplyTemplate();
  470. var dataContexts = target.Presenter.Panel.Children
  471. .Do(x => (x as ContentPresenter)?.UpdateChild())
  472. .Cast<Control>()
  473. .Select(x => x.DataContext)
  474. .ToList();
  475. Assert.Equal(
  476. new object[] { items[0], items[1], "Base", "Base" },
  477. dataContexts);
  478. }
  479. [Fact]
  480. public void Control_Item_Should_Not_Be_NameScope()
  481. {
  482. var items = new object[]
  483. {
  484. new TextBlock(),
  485. };
  486. var target = new ItemsControl
  487. {
  488. Template = GetTemplate(),
  489. Items = items,
  490. };
  491. target.ApplyTemplate();
  492. target.Presenter.ApplyTemplate();
  493. var item = target.Presenter.Panel.LogicalChildren[0];
  494. Assert.Null(NameScope.GetNameScope((TextBlock)item));
  495. }
  496. [Fact]
  497. public void Focuses_Next_Item_On_Key_Down()
  498. {
  499. using (UnitTestApplication.Start(TestServices.RealFocus))
  500. {
  501. var items = new object[]
  502. {
  503. new Button(),
  504. new Button(),
  505. };
  506. var target = new ItemsControl
  507. {
  508. Template = GetTemplate(),
  509. Items = items,
  510. };
  511. var root = new TestRoot { Child = target };
  512. target.ApplyTemplate();
  513. target.Presenter.ApplyTemplate();
  514. target.Presenter.Panel.Children[0].Focus();
  515. target.RaiseEvent(new KeyEventArgs
  516. {
  517. RoutedEvent = InputElement.KeyDownEvent,
  518. Key = Key.Down,
  519. });
  520. Assert.Equal(
  521. target.Presenter.Panel.Children[1],
  522. FocusManager.Instance.Current);
  523. }
  524. }
  525. [Fact]
  526. public void Does_Not_Focus_Non_Focusable_Item_On_Key_Down()
  527. {
  528. using (UnitTestApplication.Start(TestServices.RealFocus))
  529. {
  530. var items = new object[]
  531. {
  532. new Button(),
  533. new Button { Focusable = false },
  534. new Button(),
  535. };
  536. var target = new ItemsControl
  537. {
  538. Template = GetTemplate(),
  539. Items = items,
  540. };
  541. var root = new TestRoot { Child = target };
  542. target.ApplyTemplate();
  543. target.Presenter.ApplyTemplate();
  544. target.Presenter.Panel.Children[0].Focus();
  545. target.RaiseEvent(new KeyEventArgs
  546. {
  547. RoutedEvent = InputElement.KeyDownEvent,
  548. Key = Key.Down,
  549. });
  550. Assert.Equal(
  551. target.Presenter.Panel.Children[2],
  552. FocusManager.Instance.Current);
  553. }
  554. }
  555. [Fact]
  556. public void Detaching_Then_Reattaching_To_Logical_Tree_Twice_Does_Not_Throw()
  557. {
  558. // # Issue 3487
  559. var target = new ItemsControl
  560. {
  561. Template = GetTemplate(),
  562. Items = new[] { "foo", "bar" },
  563. ItemTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
  564. };
  565. var root = new TestRoot(target);
  566. root.Measure(Size.Infinity);
  567. root.Arrange(new Rect(root.DesiredSize));
  568. root.Child = null;
  569. root.Child = target;
  570. target.Measure(Size.Infinity);
  571. root.Child = null;
  572. root.Child = target;
  573. }
  574. [Fact]
  575. public void Should_Use_DisplayMemberBinding()
  576. {
  577. var target = new ItemsControl
  578. {
  579. Template = GetTemplate(),
  580. DisplayMemberBinding = new Binding("Length")
  581. };
  582. target.Items = new[] { "Foo" };
  583. target.ApplyTemplate();
  584. target.Presenter.ApplyTemplate();
  585. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  586. container.UpdateChild();
  587. Assert.Equal(container.Child!.GetValue(TextBlock.TextProperty), "3");
  588. }
  589. [Fact]
  590. public void DisplayMemberBinding_Can_Be_Changed()
  591. {
  592. var target = new ItemsControl
  593. {
  594. Template = GetTemplate(),
  595. DisplayMemberBinding = new Binding("Value")
  596. };
  597. target.Items = new[] { new Item("Foo", "Bar") };
  598. target.ApplyTemplate();
  599. target.Presenter.ApplyTemplate();
  600. var container = (ContentPresenter)target.Presenter.Panel.Children[0];
  601. container.UpdateChild();
  602. Assert.Equal(container.Child!.GetValue(TextBlock.TextProperty), "Bar");
  603. target.DisplayMemberBinding = new Binding("Caption");
  604. container = (ContentPresenter)target.Presenter.Panel.Children[0];
  605. container.UpdateChild();
  606. Assert.Equal(container.Child!.GetValue(TextBlock.TextProperty), "Foo");
  607. }
  608. [Fact]
  609. public void Cannot_Set_Both_DisplayMemberBinding_And_ItemTemplate_1()
  610. {
  611. var target = new ItemsControl
  612. {
  613. Template = GetTemplate(),
  614. DisplayMemberBinding = new Binding("Length")
  615. };
  616. Assert.Throws<InvalidOperationException>(() =>
  617. target.ItemTemplate = new FuncDataTemplate<string>((_, _) => new TextBlock()));
  618. }
  619. [Fact]
  620. public void Cannot_Set_Both_DisplayMemberBinding_And_ItemTemplate_2()
  621. {
  622. var target = new ItemsControl
  623. {
  624. Template = GetTemplate(),
  625. ItemTemplate = new FuncDataTemplate<string>((_, _) => new TextBlock()),
  626. };
  627. Assert.Throws<InvalidOperationException>(() => target.DisplayMemberBinding = new Binding("Length"));
  628. }
  629. private class Item
  630. {
  631. public Item(string value)
  632. {
  633. Value = value;
  634. }
  635. public Item(string caption, string value)
  636. {
  637. Caption = caption;
  638. Value = value;
  639. }
  640. public string Caption { get; }
  641. public string Value { get; }
  642. }
  643. private static FuncControlTemplate GetTemplate()
  644. {
  645. return new FuncControlTemplate<ItemsControl>((parent, scope) =>
  646. {
  647. return new Border
  648. {
  649. Background = new Media.SolidColorBrush(0xffffffff),
  650. Child = new ItemsPresenter
  651. {
  652. Name = "PART_ItemsPresenter",
  653. }.RegisterInNameScope(scope)
  654. };
  655. });
  656. }
  657. }
  658. }