ContentControlMixinTests.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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.Collections.Generic;
  4. using Avalonia.Collections;
  5. using Avalonia.Controls.Mixins;
  6. using Avalonia.Controls.Presenters;
  7. using Avalonia.Controls.Primitives;
  8. using Avalonia.Controls.Templates;
  9. using Avalonia.LogicalTree;
  10. using Moq;
  11. using Xunit;
  12. namespace Avalonia.Controls.UnitTests.Mixins
  13. {
  14. public class ContentControlMixinTests
  15. {
  16. [Fact]
  17. public void Multiple_Mixin_Usages_Should_Not_Throw()
  18. {
  19. var target = new TestControl()
  20. {
  21. Template = new FuncControlTemplate(_ => new Panel
  22. {
  23. Children =
  24. {
  25. new ContentPresenter { Name = "Content_1_Presenter" },
  26. new ContentPresenter { Name = "Content_2_Presenter" }
  27. }
  28. })
  29. };
  30. var ex = Record.Exception(() => target.ApplyTemplate());
  31. Assert.Null(ex);
  32. }
  33. [Fact]
  34. public void Replacing_Template_Releases_Events()
  35. {
  36. var p1 = new ContentPresenter { Name = "Content_1_Presenter" };
  37. var p2 = new ContentPresenter { Name = "Content_2_Presenter" };
  38. var callIndex = -1;
  39. var called = new bool[4];
  40. void Callback()
  41. {
  42. if (callIndex >= 0)
  43. called[callIndex] = true;
  44. }
  45. var listMock = new Mock<IAvaloniaList<ILogical>>();
  46. listMock.Setup(l => l.Contains(It.IsAny<ILogical>())).Returns(false).Callback(Callback);
  47. var list = listMock.Object;
  48. var target = new TestControl(list)
  49. {
  50. Template = new FuncControlTemplate(_ => new Panel
  51. {
  52. Children =
  53. {
  54. p1,
  55. p2
  56. }
  57. })
  58. };
  59. target.ApplyTemplate();
  60. callIndex = 0;
  61. p1.Content = new Control();
  62. p1.UpdateChild();
  63. callIndex = 1;
  64. p2.Content = new Control();
  65. p2.UpdateChild();
  66. target.Template = null;
  67. callIndex = 2;
  68. p1.Content = new Control();
  69. p1.UpdateChild();
  70. callIndex = 3;
  71. p2.Content = new Control();
  72. p2.UpdateChild();
  73. Assert.Equal(new[] { true, true, false, false }, called);
  74. }
  75. private class TestControl : TemplatedControl
  76. {
  77. public static readonly StyledProperty<object> Content1Property =
  78. AvaloniaProperty.Register<TestControl, object>(nameof(Content1));
  79. public static readonly StyledProperty<object> Content2Property =
  80. AvaloniaProperty.Register<TestControl, object>(nameof(Content2));
  81. static TestControl()
  82. {
  83. ContentControlMixin.Attach<TestControl>(Content1Property, x => x.GetLogicalChildren(), "Content_1_Presenter");
  84. ContentControlMixin.Attach<TestControl>(Content2Property, x => x.GetLogicalChildren(), "Content_2_Presenter");
  85. }
  86. private IAvaloniaList<ILogical> _mock;
  87. public TestControl()
  88. {
  89. }
  90. public TestControl(IAvaloniaList<ILogical> mock)
  91. {
  92. _mock = mock;
  93. }
  94. public IAvaloniaList<ILogical> GetLogicalChildren()
  95. {
  96. return _mock ?? LogicalChildren;
  97. }
  98. public object Content1
  99. {
  100. get { return GetValue(Content1Property); }
  101. set { SetValue(Content1Property, value); }
  102. }
  103. public object Content2
  104. {
  105. get { return GetValue(Content2Property); }
  106. set { SetValue(Content2Property, value); }
  107. }
  108. }
  109. }
  110. }