/Silverlight4/Source/Controls.Testing.Toolkit/Common/ItemContainerGeneratorTest.cs

https://github.com/kvervo/HorizontalLoopingSelector · C# · 1074 lines · 911 code · 65 blank · 98 comment · 7 complexity · 962fb666655104934c0eb6c9b148c30e MD5 · raw file

  1. // (c) Copyright Microsoft Corporation.
  2. // This source is subject to the Microsoft Public License (Ms-PL).
  3. // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
  4. // All other rights reserved.
  5. using System.Collections.Generic;
  6. using System.Collections.ObjectModel;
  7. using System.Windows.Automation.Peers;
  8. using System.Windows.Automation.Provider;
  9. using System.Windows.Media;
  10. using Microsoft.Silverlight.Testing;
  11. using Microsoft.VisualStudio.TestTools.UnitTesting;
  12. namespace System.Windows.Controls.Testing
  13. {
  14. /// <summary>
  15. /// ItemContainerGenerator unit tests.
  16. /// </summary>
  17. [TestClass]
  18. public partial class ItemContainerGeneratorTest : TestBase
  19. {
  20. /// <summary>
  21. /// Initializes a new instance of the ItemContainerGeneratorTest class.
  22. /// </summary>
  23. public ItemContainerGeneratorTest()
  24. : base()
  25. {
  26. }
  27. /// <summary>
  28. /// Verify the items aren't created outside of the visual tree.
  29. /// </summary>
  30. [TestMethod]
  31. [Description("Verify the items aren't created outside of the visual tree.")]
  32. public virtual void NoItemsOutsideOfTree()
  33. {
  34. int[] source = new int[] { 1, 2, 3 };
  35. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  36. for (int i = 0; i < items.Items.Count; i++)
  37. {
  38. Assert.AreEqual(source[i], items.Items[i], "Item {0} has unexpected value", i);
  39. Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(i), "Container {0} should be null!", i);
  40. }
  41. }
  42. /// <summary>
  43. /// Verify the items are created once it's in the visual tree.
  44. /// </summary>
  45. [TestMethod]
  46. [Asynchronous]
  47. [Description("Verify the items are created once it's in the visual tree.")]
  48. public virtual void ItemsCreatedInTree()
  49. {
  50. int[] source = new int[] { 1, 2, 3 };
  51. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  52. TestAsync(
  53. items,
  54. () =>
  55. {
  56. for (int i = 0; i < items.Items.Count; i++)
  57. {
  58. Assert.AreEqual(source[i], items.Items[i], "Item {0} has unexpected value", i);
  59. Assert.IsNotNull(items.ItemContainerGenerator.ContainerFromIndex(i), "Container {0} should not be null!", i);
  60. }
  61. });
  62. }
  63. #region Container Mapping
  64. /// <summary>
  65. /// Get a container from its index.
  66. /// </summary>
  67. [TestMethod]
  68. [Asynchronous]
  69. [Description("Get a container from its index.")]
  70. [Priority(0)]
  71. public virtual void GetContainerFromIndex()
  72. {
  73. int[] source = new int[] { 1, 2, 3 };
  74. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  75. TestAsync(
  76. items,
  77. () =>
  78. {
  79. for (int i = 0; i < items.Items.Count; i++)
  80. {
  81. DependencyObject container = items.ItemContainerGenerator.ContainerFromIndex(i);
  82. Assert.IsNotNull(container, "Container {0} should not be null!", i);
  83. ContentPresenter presenter = container as ContentPresenter;
  84. Assert.IsNotNull(presenter, "Presenter {0} should not be null!", i);
  85. Assert.AreEqual(items.Items[i], presenter.Content, "Item {0} has unexpected value", i);
  86. }
  87. });
  88. }
  89. /// <summary>
  90. /// Try to get a container for an index out of range.
  91. /// </summary>
  92. [TestMethod]
  93. [Asynchronous]
  94. [Description("Try to get a container for an index out of range.")]
  95. public virtual void GetContainerFromIndexOutOfRange()
  96. {
  97. int[] source = new int[] { 1, 2, 3 };
  98. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  99. TestAsync(
  100. items,
  101. // () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(-1), "Index -1 should return null!"), WPF throws IndexOutOfRange
  102. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(3), "Index 3 should return null!"),
  103. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(4), "Index 3 should return null!"),
  104. // () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(int.MinValue), "Index int.MinValue should return null!"), WPF throws IndexOutOfRange
  105. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(int.MaxValue), "Index int.MaxValue should return null!"));
  106. }
  107. /// <summary>
  108. /// Try to get a container when there is no ItemsHost.
  109. /// </summary>
  110. [TestMethod]
  111. [Description("Try to get a container when there is no ItemsHost.")]
  112. public virtual void GetContainerFromIndexNoItemsHost()
  113. {
  114. int[] source = new int[] { 1, 2, 3 };
  115. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  116. Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(0), "Index 0 should return null!");
  117. Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(1), "Index 1 should return null!");
  118. Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(2), "Index 2 should return null!");
  119. }
  120. /// <summary>
  121. /// Try to get a container when the Items have been cleared.
  122. /// </summary>
  123. [TestMethod]
  124. [Asynchronous]
  125. [Description("Try to get a container when the Items have been cleared.")]
  126. public virtual void GetContainerFromIndexNoItems()
  127. {
  128. int[] source = new int[] { 1, 2, 3 };
  129. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  130. TestAsync(
  131. items,
  132. () => Assert.IsNotNull(items.ItemContainerGenerator.ContainerFromIndex(0), "Index 0 should not return null!"),
  133. () => items.ItemsSource = null,
  134. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromIndex(0), "Index 0 should return null after clearing!"));
  135. }
  136. /// <summary>
  137. /// Try to get the container from an item.
  138. /// </summary>
  139. [TestMethod]
  140. [Asynchronous]
  141. [Description("Try to get the container from an item.")]
  142. [Priority(0)]
  143. public virtual void GetContainerFromItem()
  144. {
  145. int[] source = new int[] { 1, 2, 3 };
  146. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  147. TestAsync(
  148. items,
  149. () =>
  150. {
  151. for (int i = 0; i < items.Items.Count; i++)
  152. {
  153. DependencyObject container = items.ItemContainerGenerator.ContainerFromItem(source[i]);
  154. Assert.IsNotNull(container, "Container {0} should not be null!", i);
  155. ContentPresenter presenter = container as ContentPresenter;
  156. Assert.IsNotNull(presenter, "Presenter {0} should not be null!", i);
  157. Assert.AreEqual(source[i], presenter.Content, "Item {0} has unexpected value", i);
  158. }
  159. });
  160. }
  161. /// <summary>
  162. /// Try to get the container from an item using reference types.
  163. /// </summary>
  164. [TestMethod]
  165. [Asynchronous]
  166. [Description("Try to get the container from an item using reference types.")]
  167. public virtual void GetContainerFromItemWithReferenceTypes()
  168. {
  169. string[] source = new string[] { "Hello", "World" };
  170. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  171. TestAsync(
  172. items,
  173. () =>
  174. {
  175. for (int i = 0; i < items.Items.Count; i++)
  176. {
  177. DependencyObject container = items.ItemContainerGenerator.ContainerFromItem(source[i]);
  178. Assert.IsNotNull(container, "Container {0} should not be null!", i);
  179. ContentPresenter presenter = container as ContentPresenter;
  180. Assert.IsNotNull(presenter, "Presenter {0} should not be null!", i);
  181. Assert.AreEqual(source[i], presenter.Content, "Item {0} has unexpected value", i);
  182. }
  183. });
  184. }
  185. /// <summary>
  186. /// Try to get the container from an item not in the collection.
  187. /// </summary>
  188. [TestMethod]
  189. [Asynchronous]
  190. [Description("Try to get the container from an item not in the collection.")]
  191. public virtual void GetContainerFromItemNotInCollection()
  192. {
  193. int[] source = new int[] { 1, 2, 3 };
  194. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  195. TestAsync(
  196. items,
  197. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromItem(4), "Found no container for 4!"),
  198. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromItem(new object()), "Found no container for new object!"),
  199. () => Assert.IsNull(items.ItemContainerGenerator.ContainerFromItem(new object()), "Found no container for null!"));
  200. }
  201. /// <summary>
  202. /// Try to get a container for items with the same value.
  203. /// </summary>
  204. [TestMethod]
  205. [Asynchronous]
  206. [Description("Try to get a container for items with the same value.")]
  207. public virtual void GetContainerFromItemWithSameValue()
  208. {
  209. int[] source = new int[] { 1, 1, 1, 1, 1, 1, 1 };
  210. HeaderedItemsControl items = new HeaderedItemsControl { ItemsSource = source };
  211. TestAsync(
  212. items,
  213. () =>
  214. {
  215. // Get the first item
  216. DependencyObject first = items.ItemContainerGenerator.ContainerFromIndex(0);
  217. for (int i = 0; i < items.Items.Count; i++)
  218. {
  219. DependencyObject container = items.ItemContainerGenerator.ContainerFromItem(source[i]);
  220. Assert.AreEqual(first, container, "Container for item {0} should be the first in the list!", i);
  221. }
  222. });
  223. }
  224. /// <summary>
  225. /// Try to get the index of a container.
  226. /// </summary>
  227. [TestMethod]
  228. [Asynchronous]
  229. [Description("Try to get the index of a container.")]
  230. [Priority(0)]
  231. public virtual void GetIndexFromContainer()
  232. {
  233. TreeView view = new TreeView();
  234. TreeViewItem first = new TreeViewItem { Header = "First" };
  235. TreeViewItem second = new TreeViewItem { Header = "Second" };
  236. view.Items.Add(first);
  237. view.Items.Add(second);
  238. TestAsync(
  239. view,
  240. () => Assert.AreEqual(0, view.ItemContainerGenerator.IndexFromContainer(first), "First should be at position 0!"),
  241. () => Assert.AreEqual(1, view.ItemContainerGenerator.IndexFromContainer(second), "Second should be at position 1!"));
  242. }
  243. /// <summary>
  244. /// Try to get the index of a null container.
  245. /// </summary>
  246. [TestMethod]
  247. [ExpectedException(typeof(ArgumentNullException))]
  248. [Description("Try to get the index of a null container.")]
  249. public virtual void GetIndexFromContainerNull()
  250. {
  251. TreeView view = new TreeView { ItemsSource = new[] { 1, 2, 3 } };
  252. view.ItemContainerGenerator.IndexFromContainer(null);
  253. }
  254. /// <summary>
  255. /// Try to get the index of a non-UIElement container.
  256. /// </summary>
  257. [TestMethod]
  258. [Description("Try to get the index of a non-UIElement container.")]
  259. public virtual void GetIndexFromContainerNonUIElement()
  260. {
  261. TreeView view = new TreeView { ItemsSource = new[] { 1, 2, 3 } };
  262. Assert.AreEqual(-1, view.ItemContainerGenerator.IndexFromContainer(new SolidColorBrush(Colors.Black)), "Expected to not find a non-UIElement DependencyObject!");
  263. }
  264. /// <summary>
  265. /// Try to get the index of a container not in the tree yet.
  266. /// </summary>
  267. [TestMethod]
  268. [Description("Try to get the index of a container not in the tree yet.")]
  269. public virtual void GetIndexFromContainerNotInTree()
  270. {
  271. TreeView view = new TreeView { ItemsSource = new[] { 1, 2, 3 } };
  272. TreeViewItem first = new TreeViewItem { Header = "First" };
  273. Assert.AreEqual(-1, view.ItemContainerGenerator.IndexFromContainer(first), "Expected not to find index of container!");
  274. }
  275. /// <summary>
  276. /// Try to get the item for a container.
  277. /// </summary>
  278. [TestMethod]
  279. [Asynchronous]
  280. [Description("Try to get the item for a container.")]
  281. [Priority(0)]
  282. [Bug("33637: ItemContainerGenerator.ItemFromContainer does not correctly return items", Fixed = true)]
  283. public virtual void GetItemFromContainer()
  284. {
  285. int[] source = new int[] { 1, 2, 3 };
  286. TreeView view = new TreeView { ItemsSource = source };
  287. TestAsync(
  288. view,
  289. () =>
  290. {
  291. for (int i = 0; i < view.Items.Count; i++)
  292. {
  293. TreeViewItem item = view.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
  294. Assert.IsNotNull(item, "TreeViewItem {0} should not be null!", i);
  295. Assert.AreEqual(source[i], view.ItemContainerGenerator.ItemFromContainer(item), "Item {0} has unexpected value", i);
  296. }
  297. });
  298. }
  299. /// <summary>
  300. /// Try to get the item from a null container.
  301. /// </summary>
  302. [TestMethod]
  303. [ExpectedException(typeof(ArgumentNullException))]
  304. [Description("Try to get the item from a null container.")]
  305. public virtual void GetItemFromContainerNull()
  306. {
  307. TreeView view = new TreeView { ItemsSource = new[] { 1, 2, 3 } };
  308. view.ItemContainerGenerator.ItemFromContainer(null);
  309. }
  310. /// <summary>
  311. /// Try to get the item for a container not in the Items.
  312. /// </summary>
  313. [TestMethod]
  314. [Asynchronous]
  315. [Description("Try to get the item for a container not in the Items.")]
  316. public virtual void GetItemFromContainerNotInItems()
  317. {
  318. TreeView view = new TreeView();
  319. TreeViewItem first = new TreeViewItem { Header = "First" };
  320. TreeViewItem second = new TreeViewItem { Header = "Second" };
  321. view.Items.Add(first);
  322. TestAsync(
  323. view,
  324. () => Assert.AreEqual(first, view.ItemContainerGenerator.ItemFromContainer(first), "First not found!"),
  325. () => Assert.AreEqual(DependencyProperty.UnsetValue, view.ItemContainerGenerator.ItemFromContainer(second), "Second should not be found!"));
  326. }
  327. #endregion Container Mapping
  328. #region ScrollIntoView
  329. /// <summary>
  330. /// Scroll an item into view.
  331. /// </summary>
  332. [TestMethod]
  333. [Asynchronous]
  334. [Description("Scroll an item into view.")]
  335. [Priority(0)]
  336. public virtual void ScrollIntoView()
  337. {
  338. TreeView view = new TreeView { Width = 20, Height = 20 };
  339. TreeViewItem first = new TreeViewItem { Header = "First" };
  340. TreeViewItem second = new TreeViewItem { Header = 2 };
  341. view.Items.Add(first);
  342. view.Items.Add(second);
  343. TreeViewAutomationPeer viewPeer = null;
  344. TreeViewItemAutomationPeer firstPeer = null;
  345. IScrollItemProvider firstProvider = null;
  346. TreeViewItemAutomationPeer secondPeer = null;
  347. IScrollItemProvider secondProvider = null;
  348. TestAsync(
  349. view,
  350. () => viewPeer = FrameworkElementAutomationPeer.CreatePeerForElement(view) as TreeViewAutomationPeer,
  351. () => firstPeer = FrameworkElementAutomationPeer.CreatePeerForElement(first) as TreeViewItemAutomationPeer,
  352. () => secondPeer = FrameworkElementAutomationPeer.CreatePeerForElement(second) as TreeViewItemAutomationPeer,
  353. () => firstProvider = firstPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  354. () => secondProvider = secondPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  355. () => secondProvider.ScrollIntoView());
  356. }
  357. /// <summary>
  358. /// Scroll an item into view both horizontally and vertically.
  359. /// </summary>
  360. [TestMethod]
  361. [Asynchronous]
  362. [Description("Scroll an item into view both horizontally and vertically.")]
  363. public virtual void ScrollItemIntoViewBoth()
  364. {
  365. TreeView view = new TreeView { Width = 20, Height = 20 };
  366. TreeViewItem first = new TreeViewItem { Header = "First", IsExpanded = true };
  367. TreeViewItem second = new TreeViewItem { Header = 2 };
  368. view.Items.Add(first);
  369. first.Items.Add(second);
  370. TreeViewAutomationPeer viewPeer = null;
  371. TreeViewItemAutomationPeer firstPeer = null;
  372. IScrollItemProvider firstProvider = null;
  373. TreeViewItemAutomationPeer secondPeer = null;
  374. IScrollItemProvider secondProvider = null;
  375. TestAsync(
  376. view,
  377. () => viewPeer = FrameworkElementAutomationPeer.CreatePeerForElement(view) as TreeViewAutomationPeer,
  378. () => firstPeer = FrameworkElementAutomationPeer.CreatePeerForElement(first) as TreeViewItemAutomationPeer,
  379. () => secondPeer = FrameworkElementAutomationPeer.CreatePeerForElement(second) as TreeViewItemAutomationPeer,
  380. () => firstProvider = firstPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  381. () => secondProvider = secondPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  382. () => secondProvider.ScrollIntoView(),
  383. () => firstProvider.ScrollIntoView(),
  384. () => secondProvider.ScrollIntoView(),
  385. () => firstProvider.ScrollIntoView());
  386. }
  387. /// <summary>
  388. /// Scroll an item into view that is already in view.
  389. /// </summary>
  390. [TestMethod]
  391. [Asynchronous]
  392. [Description("Scroll an item into view that is already in view.")]
  393. public virtual void ScrollItemIntoViewAlreadyInView()
  394. {
  395. TreeView view = new TreeView();
  396. TreeViewItem first = new TreeViewItem { Header = "First" };
  397. TreeViewItem second = new TreeViewItem { Header = 2 };
  398. view.Items.Add(first);
  399. view.Items.Add(second);
  400. TreeViewAutomationPeer viewPeer = null;
  401. TreeViewItemAutomationPeer firstPeer = null;
  402. IScrollItemProvider firstProvider = null;
  403. TreeViewItemAutomationPeer secondPeer = null;
  404. IScrollItemProvider secondProvider = null;
  405. TestAsync(
  406. view,
  407. () => viewPeer = FrameworkElementAutomationPeer.CreatePeerForElement(view) as TreeViewAutomationPeer,
  408. () => firstPeer = FrameworkElementAutomationPeer.CreatePeerForElement(first) as TreeViewItemAutomationPeer,
  409. () => secondPeer = FrameworkElementAutomationPeer.CreatePeerForElement(second) as TreeViewItemAutomationPeer,
  410. () => firstProvider = firstPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  411. () => secondProvider = secondPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  412. () => firstProvider.ScrollIntoView());
  413. }
  414. /// <summary>
  415. /// Scroll an item into view when there's no ScrollHost.
  416. /// </summary>
  417. [TestMethod]
  418. [Asynchronous]
  419. [Description("Scroll an item into view when there's no ScrollHost.")]
  420. public virtual void ScrollIntoViewNoScrollHost()
  421. {
  422. TreeView view = new TreeView();
  423. TreeViewItem first = new TreeViewItem { Header = "First" };
  424. TreeViewItem second = new TreeViewItem { Header = 2 };
  425. view.Items.Add(first);
  426. view.Items.Add(second);
  427. TreeViewAutomationPeer viewPeer = null;
  428. TreeViewItemAutomationPeer firstPeer = null;
  429. IScrollItemProvider firstProvider = null;
  430. TreeViewItemAutomationPeer secondPeer = null;
  431. IScrollItemProvider secondProvider = null;
  432. // Create a template without a ScrollViewer
  433. XamlBuilder<ControlTemplate> builder = new XamlBuilder<ControlTemplate>
  434. {
  435. ExplicitNamespaces = new Dictionary<string, string> { { "ctls", XamlBuilder.GetNamespace(typeof(TreeView)) } },
  436. AttributeProperties = new Dictionary<string, string> { { "TargetType", "ctls:TreeView" } },
  437. Children = new List<XamlBuilder> { new XamlBuilder<ItemsPresenter>() }
  438. };
  439. view.Template = builder.Load();
  440. TestAsync(
  441. view,
  442. () => viewPeer = FrameworkElementAutomationPeer.CreatePeerForElement(view) as TreeViewAutomationPeer,
  443. () => firstPeer = FrameworkElementAutomationPeer.CreatePeerForElement(first) as TreeViewItemAutomationPeer,
  444. () => secondPeer = FrameworkElementAutomationPeer.CreatePeerForElement(second) as TreeViewItemAutomationPeer,
  445. () => firstProvider = firstPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  446. () => secondProvider = secondPeer.GetPattern(PatternInterface.ScrollItem) as IScrollItemProvider,
  447. () => firstProvider.ScrollIntoView());
  448. }
  449. #endregion
  450. #region Prepare
  451. /// <summary>
  452. /// Verify that ItemTemplates are applied.
  453. /// </summary>
  454. [TestMethod]
  455. [Asynchronous]
  456. [Description("Verify that ItemTemplates are applied.")]
  457. [Priority(0)]
  458. public virtual void ApplyItemTemplate()
  459. {
  460. XamlBuilder<Grid> builder = new XamlBuilder<Grid>
  461. {
  462. ExplicitNamespaces = new Dictionary<string, string>
  463. {
  464. { "toolkit", XamlBuilder.GetNamespace(typeof(ObjectCollection)) },
  465. { "ctl", XamlBuilder.GetNamespace(typeof(System.Windows.Controls.TreeView)) },
  466. { "sys", XamlBuilder.GetNamespace(typeof(int)) },
  467. },
  468. ElementProperties = new Dictionary<string, XamlBuilder>
  469. {
  470. {
  471. "Resources",
  472. new XamlBuilder<DataTemplate>
  473. {
  474. Key = "template",
  475. Children = new List<XamlBuilder>
  476. {
  477. new XamlBuilder<ContentControl>
  478. {
  479. Name = "TemplateContent",
  480. AttributeProperties = new Dictionary<string, string>
  481. {
  482. { "Content", "{Binding}" },
  483. { "Foreground", "Red" }
  484. }
  485. }
  486. }
  487. }
  488. }
  489. },
  490. Children = new List<XamlBuilder>
  491. {
  492. new XamlBuilder<TreeView>
  493. {
  494. AttributeProperties = new Dictionary<string, string> { { "ItemTemplate", "{StaticResource template}" } },
  495. ElementProperties = new Dictionary<string, XamlBuilder>
  496. {
  497. {
  498. "ItemsSource",
  499. new XamlBuilder<ObjectCollection>
  500. {
  501. Children = new List<XamlBuilder>
  502. {
  503. new XamlBuilder<int> { Content = "1" },
  504. new XamlBuilder<int> { Content = "2" },
  505. new XamlBuilder<int> { Content = "3" }
  506. }
  507. }
  508. }
  509. }
  510. }
  511. }
  512. };
  513. Grid root = builder.Load();
  514. TreeView view = null;
  515. TreeViewItem first = null;
  516. ContentControl header = null;
  517. TestAsync(
  518. 5,
  519. root,
  520. () => view = root.Children[0] as TreeView,
  521. () => first = view.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  522. () => Assert.IsNotNull(first, "First item should not be null!"),
  523. () => Assert.AreEqual(1, first.Header, "Unexpected header!"),
  524. () => header = first.GetVisualChild("TemplateContent") as ContentControl,
  525. () => Assert.IsNotNull(header, "Header should not be null!"));
  526. }
  527. /// <summary>
  528. /// Verify that HierarchicalDataTemplates are applied.
  529. /// </summary>
  530. [TestMethod]
  531. [Asynchronous]
  532. [Description("Verify that HierarchicalDataTemplates are applied.")]
  533. [Priority(0)]
  534. public virtual void ApplyHierarchicalDataTemplate()
  535. {
  536. XamlBuilder<Grid> builder = new XamlBuilder<Grid>
  537. {
  538. ExplicitNamespaces = new Dictionary<string, string>
  539. {
  540. { "common", XamlBuilder.GetNamespace(typeof(HierarchicalDataTemplate)) },
  541. { "ctl", XamlBuilder.GetNamespace(typeof(TreeViewItem)) },
  542. { "sys", XamlBuilder.GetNamespace(typeof(int)) }
  543. },
  544. ElementProperties = new Dictionary<string, XamlBuilder>
  545. {
  546. {
  547. "Resources",
  548. new XamlBuilder<HierarchicalDataTemplate>
  549. {
  550. Key = "template",
  551. AttributeProperties = new Dictionary<string, string> { { "ItemsSource", "{Binding Children}" } },
  552. Children = new List<XamlBuilder>
  553. {
  554. new XamlBuilder<ContentControl>
  555. {
  556. Name = "TemplateContent",
  557. AttributeProperties = new Dictionary<string, string>
  558. {
  559. { "Content", "{Binding Element}" },
  560. { "Foreground", "Red" }
  561. }
  562. }
  563. }
  564. }
  565. }
  566. },
  567. Children = new List<XamlBuilder>
  568. {
  569. new XamlBuilder<TreeView>
  570. {
  571. AttributeProperties = new Dictionary<string, string> { { "ItemTemplate", "{StaticResource template}" } },
  572. }
  573. }
  574. };
  575. Grid root = builder.Load();
  576. TreeView view = null;
  577. TreeViewItem item = null;
  578. Hierarchy textbox = null;
  579. List<Hierarchy> items = new List<Hierarchy>()
  580. {
  581. new Hierarchy { Element = "Brush" },
  582. new Hierarchy { Element = "Style" },
  583. new Hierarchy
  584. {
  585. Element = "UIElement",
  586. Children = new Collection<Hierarchy>
  587. {
  588. new Hierarchy
  589. {
  590. Element = "FrameworkElement",
  591. Children = new Collection<Hierarchy>
  592. {
  593. new Hierarchy
  594. {
  595. Element = "Control",
  596. Children = new Collection<Hierarchy>
  597. {
  598. new Hierarchy { Element = "TextBox" }
  599. }
  600. }
  601. }
  602. }
  603. }
  604. },
  605. new Hierarchy { Element = "VisualStateManager" }
  606. };
  607. TestAsync(
  608. 5,
  609. root,
  610. () => view = root.Children[0] as TreeView,
  611. () => view.ItemsSource = items,
  612. () => item = view.ItemContainerGenerator.ContainerFromIndex(2) as TreeViewItem,
  613. () => item.IsExpanded = true,
  614. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  615. () => item.IsExpanded = true,
  616. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  617. () => item.IsExpanded = true,
  618. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  619. () => textbox = item.Header as Hierarchy,
  620. () => Assert.IsNotNull(textbox, "TextBox reference should not be null!"),
  621. () => Assert.AreEqual("TextBox", textbox.Element, "Unexpected Element!"));
  622. }
  623. /// <summary>
  624. /// Apply a HierarchicalDataTemplate with ItemContainerStyle set.
  625. /// </summary>
  626. [TestMethod]
  627. [Asynchronous]
  628. [Description("Apply a HierarchicalDataTemplate with ItemContainerStyle set.")]
  629. [Bug("532192 - TreeView - HierarchicalDataTemplate.ItemContainerStyle doesn't get picked up", Fixed = true)]
  630. [Priority(0)]
  631. public virtual void ApplyHierarchicalDataTemplateWithStyle()
  632. {
  633. XamlBuilder<Grid> builder = new XamlBuilder<Grid>
  634. {
  635. ExplicitNamespaces = new Dictionary<string, string>
  636. {
  637. { "common", XamlBuilder.GetNamespace(typeof(HierarchicalDataTemplate)) },
  638. { "ctl", XamlBuilder.GetNamespace(typeof(TreeViewItem)) },
  639. { "sys", XamlBuilder.GetNamespace(typeof(int)) }
  640. },
  641. ElementProperties = new Dictionary<string, XamlBuilder>
  642. {
  643. {
  644. "Resources",
  645. new XamlBuilder<Style>
  646. {
  647. Key = "itemStyle",
  648. AttributeProperties = new Dictionary<string, string> { { "TargetType", "ctl:TreeViewItem" } },
  649. Children = new List<XamlBuilder>
  650. {
  651. new XamlBuilder<Setter>
  652. {
  653. AttributeProperties = new Dictionary<string, string>
  654. {
  655. { "Property", "FontSize" },
  656. { "Value", "15" }
  657. }
  658. }
  659. }
  660. }
  661. }
  662. },
  663. Children = new List<XamlBuilder>
  664. {
  665. new XamlBuilder<Grid>
  666. {
  667. ElementProperties = new Dictionary<string, XamlBuilder>
  668. {
  669. {
  670. "Resources",
  671. new XamlBuilder<HierarchicalDataTemplate>
  672. {
  673. Key = "template",
  674. AttributeProperties = new Dictionary<string, string>
  675. {
  676. { "ItemsSource", "{Binding Children}" },
  677. { "ItemContainerStyle", "{StaticResource itemStyle}" }
  678. },
  679. Children = new List<XamlBuilder>
  680. {
  681. new XamlBuilder<ContentControl>
  682. {
  683. Name = "TemplateContent",
  684. AttributeProperties = new Dictionary<string, string>
  685. {
  686. { "Content", "{Binding Element}" }
  687. }
  688. }
  689. }
  690. }
  691. }
  692. },
  693. Children = new List<XamlBuilder>
  694. {
  695. new XamlBuilder<TreeView>
  696. {
  697. AttributeProperties = new Dictionary<string, string>
  698. {
  699. { "ItemTemplate", "{StaticResource template}" },
  700. { "ItemContainerStyle", "{StaticResource itemStyle}" }
  701. },
  702. }
  703. }
  704. }
  705. }
  706. };
  707. Grid root = builder.Load();
  708. TreeView view = null;
  709. TreeViewItem item = null;
  710. List<Hierarchy> items = new List<Hierarchy>()
  711. {
  712. new Hierarchy { Element = "Brush" },
  713. new Hierarchy { Element = "Style" },
  714. new Hierarchy
  715. {
  716. Element = "UIElement",
  717. Children = new Collection<Hierarchy>
  718. {
  719. new Hierarchy
  720. {
  721. Element = "FrameworkElement",
  722. Children = new Collection<Hierarchy>
  723. {
  724. new Hierarchy
  725. {
  726. Element = "Control",
  727. Children = new Collection<Hierarchy>
  728. {
  729. new Hierarchy { Element = "TextBox" }
  730. }
  731. }
  732. }
  733. }
  734. }
  735. },
  736. new Hierarchy { Element = "VisualStateManager" }
  737. };
  738. TestAsync(
  739. 5,
  740. root,
  741. () => view = (root.Children[0] as Grid).Children[0] as TreeView,
  742. () => view.ItemsSource = items,
  743. () => item = view.ItemContainerGenerator.ContainerFromIndex(2) as TreeViewItem,
  744. () => Assert.AreEqual(15.0, item.FontSize, "Style not applied to first item!"),
  745. () => item.IsExpanded = true,
  746. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  747. () => Assert.AreEqual(15.0, item.FontSize, "Style not applied to second item!"),
  748. () => item.IsExpanded = true,
  749. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  750. () => Assert.AreEqual(15.0, item.FontSize, "Style not applied to third item!"),
  751. () => item.IsExpanded = true);
  752. }
  753. /// <summary>
  754. /// Apply a HierarchicalDataTemplate with ItemTemplate set.
  755. /// </summary>
  756. [TestMethod]
  757. [Asynchronous]
  758. [Description("Apply a HierarchicalDataTemplate with ItemTemplate set.")]
  759. [Priority(0)]
  760. public virtual void ApplyHierarchicalDataTemplateWithItemTemplate()
  761. {
  762. XamlBuilder<Grid> builder = new XamlBuilder<Grid>
  763. {
  764. ExplicitNamespaces = new Dictionary<string, string>
  765. {
  766. { "common", XamlBuilder.GetNamespace(typeof(HierarchicalDataTemplate)) },
  767. { "ctl", XamlBuilder.GetNamespace(typeof(TreeViewItem)) },
  768. { "sys", XamlBuilder.GetNamespace(typeof(int)) }
  769. },
  770. ElementProperties = new Dictionary<string, XamlBuilder>
  771. {
  772. {
  773. "Resources",
  774. new XamlBuilder<DataTemplate>
  775. {
  776. Key = "itemTemplate",
  777. Children = new List<XamlBuilder>
  778. {
  779. new XamlBuilder<ContentControl>
  780. {
  781. Name = "TemplateContent",
  782. AttributeProperties = new Dictionary<string, string>
  783. {
  784. { "Content", "{Binding Element}" },
  785. { "FontWeight", "Bold" }
  786. }
  787. }
  788. }
  789. }
  790. }
  791. },
  792. Children = new List<XamlBuilder>
  793. {
  794. new XamlBuilder<Grid>
  795. {
  796. ElementProperties = new Dictionary<string, XamlBuilder>
  797. {
  798. {
  799. "Resources",
  800. new XamlBuilder<HierarchicalDataTemplate>
  801. {
  802. Key = "template",
  803. AttributeProperties = new Dictionary<string, string>
  804. {
  805. { "ItemsSource", "{Binding Children}" },
  806. { "ItemTemplate", "{StaticResource itemTemplate}" }
  807. },
  808. Children = new List<XamlBuilder>
  809. {
  810. new XamlBuilder<ContentControl>
  811. {
  812. Name = "TemplateContent",
  813. AttributeProperties = new Dictionary<string, string>
  814. {
  815. { "Content", "{Binding Element}" },
  816. { "FontStyle", "Italic" }
  817. }
  818. }
  819. }
  820. }
  821. }
  822. },
  823. Children = new List<XamlBuilder>
  824. {
  825. new XamlBuilder<TreeView>
  826. {
  827. AttributeProperties = new Dictionary<string, string>
  828. {
  829. { "ItemTemplate", "{StaticResource template}" }
  830. },
  831. }
  832. }
  833. }
  834. }
  835. };
  836. Grid root = builder.Load();
  837. TreeView view = null;
  838. TreeViewItem item = null;
  839. List<Hierarchy> items = new List<Hierarchy>()
  840. {
  841. new Hierarchy { Element = "Brush" },
  842. new Hierarchy { Element = "Style" },
  843. new Hierarchy
  844. {
  845. Element = "UIElement",
  846. Children = new Collection<Hierarchy>
  847. {
  848. new Hierarchy
  849. {
  850. Element = "FrameworkElement",
  851. Children = new Collection<Hierarchy>
  852. {
  853. new Hierarchy
  854. {
  855. Element = "Control",
  856. Children = new Collection<Hierarchy>
  857. {
  858. new Hierarchy { Element = "TextBox" }
  859. }
  860. }
  861. }
  862. }
  863. }
  864. },
  865. new Hierarchy { Element = "VisualStateManager" }
  866. };
  867. TestAsync(
  868. 5,
  869. root,
  870. () => view = (root.Children[0] as Grid).Children[0] as TreeView,
  871. () => view.ItemsSource = items,
  872. () => item = view.ItemContainerGenerator.ContainerFromIndex(2) as TreeViewItem,
  873. () => item.IsExpanded = true,
  874. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  875. () => Assert.AreEqual(0, item.Items.Count, "Only the first level should have nested items!"));
  876. }
  877. /// <summary>
  878. /// Apply a HierarchicalDataTemplate and then set ItemContainerStyle.
  879. /// </summary>
  880. [TestMethod]
  881. [Asynchronous]
  882. [Description("Apply a HierarchicalDataTemplate and then set ItemContainerStyle.")]
  883. public virtual void ApplyHierarchicalDataTemplateThenSetStyle()
  884. {
  885. XamlBuilder<Grid> builder = new XamlBuilder<Grid>
  886. {
  887. ExplicitNamespaces = new Dictionary<string, string>
  888. {
  889. { "common", XamlBuilder.GetNamespace(typeof(HierarchicalDataTemplate)) },
  890. { "ctl", XamlBuilder.GetNamespace(typeof(TreeViewItem)) },
  891. { "sys", XamlBuilder.GetNamespace(typeof(int)) }
  892. },
  893. ElementProperties = new Dictionary<string, XamlBuilder>
  894. {
  895. {
  896. "Resources",
  897. new XamlBuilder<HierarchicalDataTemplate>
  898. {
  899. Key = "template",
  900. AttributeProperties = new Dictionary<string, string> { { "ItemsSource", "{Binding Children}" } },
  901. Children = new List<XamlBuilder>
  902. {
  903. new XamlBuilder<ContentControl>
  904. {
  905. Name = "TemplateContent",
  906. AttributeProperties = new Dictionary<string, string>
  907. {
  908. { "Content", "{Binding Element}" }
  909. }
  910. }
  911. }
  912. }
  913. }
  914. },
  915. Children = new List<XamlBuilder>
  916. {
  917. new XamlBuilder<TreeView>
  918. {
  919. AttributeProperties = new Dictionary<string, string> { { "ItemTemplate", "{StaticResource template}" } },
  920. }
  921. }
  922. };
  923. Grid root = builder.Load();
  924. TreeView view = null;
  925. TreeViewItem item = null;
  926. List<Hierarchy> items = new List<Hierarchy>()
  927. {
  928. new Hierarchy { Element = "Brush" },
  929. new Hierarchy { Element = "Style" },
  930. new Hierarchy
  931. {
  932. Element = "UIElement",
  933. Children = new Collection<Hierarchy>
  934. {
  935. new Hierarchy
  936. {
  937. Element = "FrameworkElement",
  938. Children = new Collection<Hierarchy>
  939. {
  940. new Hierarchy
  941. {
  942. Element = "Control",
  943. Children = new Collection<Hierarchy>
  944. {
  945. new Hierarchy { Element = "TextBox" }
  946. }
  947. }
  948. }
  949. }
  950. }
  951. },
  952. new Hierarchy { Element = "VisualStateManager" }
  953. };
  954. Style outerStyle = new Style(typeof(TreeViewItem));
  955. outerStyle.Setters.Add(new Setter(TreeViewItem.FontSizeProperty, 20.0));
  956. Style innerStyle = new Style(typeof(TreeViewItem));
  957. innerStyle.Setters.Add(new Setter(TreeViewItem.FontSizeProperty, 10.0));
  958. TestAsync(
  959. 5,
  960. root,
  961. () => view = root.Children[0] as TreeView,
  962. () => view.ItemsSource = items,
  963. () => item = view.ItemContainerGenerator.ContainerFromIndex(2) as TreeViewItem,
  964. () => item.IsExpanded = true,
  965. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  966. () => item.IsExpanded = true,
  967. () => view.ItemContainerStyle = outerStyle,
  968. () => item = item.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  969. () => item.IsExpanded = true,
  970. () => item.ItemContainerStyle = innerStyle,
  971. () => item.ItemContainerStyle = null);
  972. }
  973. /// <summary>
  974. /// Prepare a TreeViewItem where the Header is the Item.
  975. /// </summary>
  976. [TestMethod]
  977. [Asynchronous]
  978. [Description("Prepare a TreeViewItem where the Header is the Item.")]
  979. public virtual void HeaderIsItem()
  980. {
  981. TreeView view = new TreeView { ItemsSource = new int[] { 1, 2, 3 } };
  982. TreeViewItem item = null;
  983. TestAsync(
  984. view,
  985. () => item = view.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem,
  986. () => Assert.AreEqual(1, item.Header, "Unexpected item header!"));
  987. }
  988. #endregion Prepare
  989. /// <summary>
  990. /// Removed items are no longer mapped.
  991. /// </summary>
  992. [TestMethod]
  993. [Asynchronous]
  994. [Description("Removed items are no longer mapped.")]
  995. public virtual void RemovedItemsAreNoLongerMapped()
  996. {
  997. TreeView view = new TreeView();
  998. TreeViewItem first = new TreeViewItem { Header = "First" };
  999. TreeViewItem second = new TreeViewItem { Header = "Second" };
  1000. view.Items.Add(first);
  1001. view.Items.Add(second);
  1002. TestAsync(
  1003. 5,
  1004. view,
  1005. () => view.Items.Remove(first),
  1006. () => Assert.AreEqual(-1, view.ItemContainerGenerator.IndexFromContainer(first), "First item should no longer be in the collection!"));
  1007. }
  1008. }
  1009. }