1
0

AutoDataTemplateBindingHookTest.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using Xunit;
  2. using ReactiveUI;
  3. using Avalonia.ReactiveUI;
  4. using Avalonia.UnitTests;
  5. using Avalonia.Controls;
  6. using Avalonia.Controls.Templates;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Linq;
  10. using Avalonia.VisualTree;
  11. using Avalonia.Controls.Presenters;
  12. using Splat;
  13. using System.Threading.Tasks;
  14. using System;
  15. namespace Avalonia.ReactiveUI.UnitTests
  16. {
  17. public class AutoDataTemplateBindingHookTest
  18. {
  19. public class NestedViewModel : ReactiveObject { }
  20. public class NestedView : ReactiveUserControl<NestedViewModel> { }
  21. public class ExampleViewModel : ReactiveObject
  22. {
  23. public ObservableCollection<NestedViewModel> Items { get; } = new ObservableCollection<NestedViewModel>();
  24. }
  25. public class ExampleView : ReactiveUserControl<ExampleViewModel>
  26. {
  27. public ItemsControl List { get; } = new ItemsControl
  28. {
  29. Template = GetTemplate()
  30. };
  31. public ExampleView(Action<ItemsControl> adjustItemsControl = null)
  32. {
  33. adjustItemsControl?.Invoke(List);
  34. List.ApplyTemplate();
  35. List.Presenter.ApplyTemplate();
  36. Content = List;
  37. ViewModel = new ExampleViewModel();
  38. this.OneWayBind(ViewModel, x => x.Items, x => x.List.ItemsSource);
  39. }
  40. }
  41. public AutoDataTemplateBindingHookTest()
  42. {
  43. Locator.CurrentMutable.RegisterConstant(new AutoDataTemplateBindingHook(), typeof(IPropertyBindingHook));
  44. Locator.CurrentMutable.RegisterConstant(new AvaloniaActivationForViewFetcher(), typeof(IActivationForViewFetcher));
  45. Locator.CurrentMutable.Register(() => new NestedView(), typeof(IViewFor<NestedViewModel>));
  46. }
  47. [Fact]
  48. public void Should_Apply_Data_Template_Binding_When_No_Template_Is_Set()
  49. {
  50. var view = new ExampleView();
  51. Assert.NotNull(view.List.ItemTemplate);
  52. Assert.IsType<FuncDataTemplate<object>>(view.List.ItemTemplate);
  53. }
  54. [Fact]
  55. public void Should_Use_ViewModelViewHost_As_Data_Template_By_Default()
  56. {
  57. var view = new ExampleView();
  58. view.ViewModel.Items.Add(new NestedViewModel());
  59. var child = view.List.Presenter.Panel.Children[0];
  60. var container = (ContentPresenter) child;
  61. container.UpdateChild();
  62. Assert.IsType<ViewModelViewHost>(container.Child);
  63. }
  64. [Fact]
  65. public void ViewModelViewHost_Should_Resolve_And_Embedd_Appropriate_View_Model()
  66. {
  67. var view = new ExampleView();
  68. view.ViewModel.Items.Add(new NestedViewModel());
  69. var child = view.List.Presenter.Panel.Children[0];
  70. var container = (ContentPresenter) child;
  71. container.UpdateChild();
  72. var host = (ViewModelViewHost) container.Child;
  73. Assert.IsType<NestedViewModel>(host.ViewModel);
  74. Assert.IsType<NestedViewModel>(host.DataContext);
  75. host.DataContext = "changed context";
  76. Assert.IsType<string>(host.ViewModel);
  77. Assert.IsType<string>(host.DataContext);
  78. }
  79. [Fact]
  80. public void Should_Not_Override_Data_Template_Binding_When_Item_Template_Is_Set()
  81. {
  82. var view = new ExampleView(control => control.ItemTemplate = GetItemTemplate());
  83. Assert.NotNull(view.List.ItemTemplate);
  84. Assert.IsType<FuncDataTemplate<TextBlock>>(view.List.ItemTemplate);
  85. }
  86. [Fact]
  87. public void Should_Not_Use_View_Model_View_Host_When_Item_Template_Is_Set()
  88. {
  89. var view = new ExampleView(control => control.ItemTemplate = GetItemTemplate());
  90. view.ViewModel.Items.Add(new NestedViewModel());
  91. var child = view.List.Presenter.Panel.Children[0];
  92. var container = (ContentPresenter) child;
  93. container.UpdateChild();
  94. Assert.IsType<TextBlock>(container.Child);
  95. }
  96. [Fact]
  97. public void Should_Not_Use_View_Model_View_Host_When_Data_Templates_Are_Not_Empty()
  98. {
  99. var view = new ExampleView(control => control.DataTemplates.Add(GetItemTemplate()));
  100. view.ViewModel.Items.Add(new NestedViewModel());
  101. var child = view.List.Presenter.Panel.Children[0];
  102. var container = (ContentPresenter) child;
  103. container.UpdateChild();
  104. Assert.IsType<TextBlock>(container.Child);
  105. }
  106. private static FuncDataTemplate GetItemTemplate()
  107. {
  108. return new FuncDataTemplate<TextBlock>((parent, scope) => new TextBlock());
  109. }
  110. private static FuncControlTemplate GetTemplate()
  111. {
  112. return new FuncControlTemplate<ItemsControl>((parent, scope) => new Border
  113. {
  114. Background = new Media.SolidColorBrush(0xffffffff),
  115. Child = new ItemsPresenter
  116. {
  117. Name = "PART_ItemsPresenter",
  118. }.RegisterInNameScope(scope)
  119. });
  120. }
  121. }
  122. }