diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf index b021c9f4a5..67ca3c2bf1 100644 --- a/Avalonia.Desktop.slnf +++ b/Avalonia.Desktop.slnf @@ -10,7 +10,6 @@ "samples\\IntegrationTestApp\\IntegrationTestApp.csproj", "samples\\TextTestApp\\TextTestApp.csproj", "samples\\MiniMvvm\\MiniMvvm.csproj", - "samples\\ReactiveUIDemo\\ReactiveUIDemo.csproj", "samples\\RenderDemo\\RenderDemo.csproj", "samples\\SampleControls\\ControlSamples.csproj", "samples\\Sandbox\\Sandbox.csproj", @@ -32,7 +31,6 @@ "src\\Avalonia.Native\\Avalonia.Native.csproj", "src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj", "src\\Avalonia.Vulkan\\Avalonia.Vulkan.csproj", - "src\\Avalonia.ReactiveUI\\Avalonia.ReactiveUI.csproj", "src\\Avalonia.Remote.Protocol\\Avalonia.Remote.Protocol.csproj", "src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj", "src\\Avalonia.Themes.Simple\\Avalonia.Themes.Simple.csproj", @@ -65,7 +63,6 @@ "tests\\Avalonia.LeakTests\\Avalonia.LeakTests.csproj", "tests\\Avalonia.Markup.UnitTests\\Avalonia.Markup.UnitTests.csproj", "tests\\Avalonia.Markup.Xaml.UnitTests\\Avalonia.Markup.Xaml.UnitTests.csproj", - "tests\\Avalonia.ReactiveUI.UnitTests\\Avalonia.ReactiveUI.UnitTests.csproj", "tests\\Avalonia.RenderTests.WpfCompare\\Avalonia.RenderTests.WpfCompare.csproj", "tests\\Avalonia.Skia.RenderTests\\Avalonia.Skia.RenderTests.csproj", "tests\\Avalonia.Skia.UnitTests\\Avalonia.Skia.UnitTests.csproj", diff --git a/Avalonia.sln b/Avalonia.sln index 8413f571c5..a093144f08 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -46,8 +46,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE src\Shared\StreamCompatibilityExtensions.cs = src\Shared\StreamCompatibilityExtensions.cs EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup", "src\Markup\Avalonia.Markup\Avalonia.Markup.csproj", "{6417E941-21BC-467B-A771-0DE389353CE6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.UnitTests", "tests\Avalonia.Markup.UnitTests\Avalonia.Markup.UnitTests.csproj", "{8EF392D5-1416-45AA-9956-7CBBC3229E8A}" @@ -108,7 +106,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1 build\NetCore.props = build\NetCore.props build\NetFX.props = build\NetFX.props build\NullableEnable.props = build\NullableEnable.props - build\ReactiveUI.props = build\ReactiveUI.props build\ReferenceCoreLibraries.props = build\ReferenceCoreLibraries.props build\Rx.props = build\Rx.props build\SampleApp.props = build\SampleApp.props @@ -171,8 +168,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.X11", "src\Avaloni EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformSanityChecks", "samples\PlatformSanityChecks\PlatformSanityChecks.csproj", "{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.UnitTests", "tests\Avalonia.ReactiveUI.UnitTests\Avalonia.ReactiveUI.UnitTests.csproj", "{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Dialogs", "src\Avalonia.Dialogs\Avalonia.Dialogs.csproj", "{4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.FreeDesktop", "src\Avalonia.FreeDesktop\Avalonia.FreeDesktop.csproj", "{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA}" @@ -223,8 +218,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser", "s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUIDemo", "samples\ReactiveUIDemo\ReactiveUIDemo.csproj", "{75C47156-C5D8-44BC-A5A7-E8657C2248D6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GpuInterop", "samples\GpuInterop\GpuInterop.csproj", "{C810060E-3809-4B74-A125-F11533AF9C1B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Analyzers", "src\tools\Avalonia.Analyzers\Avalonia.Analyzers.csproj", "{C692FE73-43DB-49CE-87FC-F03ED61F25C9}" @@ -360,10 +353,6 @@ Global {3E53A01A-B331-47F3-B828-4A5717E77A24}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E53A01A-B331-47F3-B828-4A5717E77A24}.Release|Any CPU.Build.0 = Release|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6417B24E-49C2-4985-8DB2-3AB9D898EC91}.Release|Any CPU.Build.0 = Release|Any CPU {6417E941-21BC-467B-A771-0DE389353CE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6417E941-21BC-467B-A771-0DE389353CE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {6417E941-21BC-467B-A771-0DE389353CE6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -496,10 +485,6 @@ Global {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|Any CPU.Build.0 = Release|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|Any CPU.Build.0 = Release|Any CPU {4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Debug|Any CPU.Build.0 = Debug|Any CPU {4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -596,10 +581,6 @@ Global {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.Build.0 = Debug|Any CPU {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.ActiveCfg = Release|Any CPU {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.Build.0 = Release|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.Build.0 = Release|Any CPU {C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C810060E-3809-4B74-A125-F11533AF9C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -757,7 +738,6 @@ Global {3C471044-3640-45E3-B1B2-16D2FF8399EE} = {E870DCD7-F46A-498D-83FC-D0FD13E0A11C} {41B02319-965D-4945-8005-C1A3D1224165} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B} = {9B9E3891-2366-4253-A952-D08BCEB71098} - {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {4D36CEC8-53F2-40A5-9A37-79AAE356E2DA} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC} = {FF237916-7150-496B-89ED-6CA3292896E7} {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E} = {FF237916-7150-496B-89ED-6CA3292896E7} @@ -778,7 +758,6 @@ Global {47F8530C-F19B-4B1A-B4D6-EB231522AE5D} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} {15B93A4C-1B46-43F6-B534-7B25B6E99932} = {9B9E3891-2366-4253-A952-D08BCEB71098} {90B08091-9BBD-4362-B712-E9F2CC62B218} = {9B9E3891-2366-4253-A952-D08BCEB71098} - {75C47156-C5D8-44BC-A5A7-E8657C2248D6} = {9B9E3891-2366-4253-A952-D08BCEB71098} {C810060E-3809-4B74-A125-F11533AF9C1B} = {9B9E3891-2366-4253-A952-D08BCEB71098} {C692FE73-43DB-49CE-87FC-F03ED61F25C9} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {DDA28789-C21A-4654-86CE-D01E81F095C5} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props deleted file mode 100644 index 299a91953c..0000000000 --- a/build/ReactiveUI.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index 13d4999054..a272c05fcf 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -296,7 +296,6 @@ partial class Build : NukeBuild RunCoreTest("Avalonia.Markup.UnitTests"); RunCoreTest("Avalonia.Markup.Xaml.UnitTests"); RunCoreTest("Avalonia.Skia.UnitTests"); - RunCoreTest("Avalonia.ReactiveUI.UnitTests"); RunCoreTest("Avalonia.Headless.NUnit.PerAssembly.UnitTests"); RunCoreTest("Avalonia.Headless.NUnit.PerTest.UnitTests"); RunCoreTest("Avalonia.Headless.XUnit.PerAssembly.UnitTests"); diff --git a/samples/Generators.Sandbox/App.xaml.cs b/samples/Generators.Sandbox/App.xaml.cs index 6118b3f177..73024efc00 100644 --- a/samples/Generators.Sandbox/App.xaml.cs +++ b/samples/Generators.Sandbox/App.xaml.cs @@ -12,9 +12,9 @@ public class App : Application { var view = new Views.SignUpView { - ViewModel = new SignUpViewModel() + DataContext = new SignUpViewModel() }; view.Show(); base.OnFrameworkInitializationCompleted(); } -} \ No newline at end of file +} diff --git a/samples/Generators.Sandbox/Controls/SignUpView.xaml b/samples/Generators.Sandbox/Controls/SignUpView.xaml index 1cfb581cf9..b256d7a31c 100644 --- a/samples/Generators.Sandbox/Controls/SignUpView.xaml +++ b/samples/Generators.Sandbox/Controls/SignUpView.xaml @@ -1,45 +1,58 @@  - + xmlns:vm="clr-namespace:Generators.Sandbox.ViewModels" + x:Class="Generators.Sandbox.Controls.SignUpView" + x:DataType="vm:SignUpViewModel"> + + + + - - - - - - - - - + - - - - - - - diff --git a/samples/ReactiveUIDemo/MainWindow.axaml.cs b/samples/ReactiveUIDemo/MainWindow.axaml.cs deleted file mode 100644 index 5bf2d476fd..0000000000 --- a/samples/ReactiveUIDemo/MainWindow.axaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using ReactiveUIDemo.ViewModels; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; - -namespace ReactiveUIDemo -{ - public class MainWindow : Window - { - public MainWindow() - { - this.InitializeComponent(); - this.DataContext = new MainWindowViewModel(); - this.AttachDevTools(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - } -} diff --git a/samples/ReactiveUIDemo/ReactiveUIDemo.csproj b/samples/ReactiveUIDemo/ReactiveUIDemo.csproj deleted file mode 100644 index 00f470fd79..0000000000 --- a/samples/ReactiveUIDemo/ReactiveUIDemo.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - Exe - $(AvsCurrentTargetFramework) - enable - - - - - - - - - - - - BarView.axaml - - - FooView.axaml - - - - - - - - diff --git a/samples/ReactiveUIDemo/ViewModels/BarViewModel.cs b/samples/ReactiveUIDemo/ViewModels/BarViewModel.cs deleted file mode 100644 index 3448453d81..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/BarViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class BarViewModel : ReactiveObject, IRoutableViewModel - { - public BarViewModel(IScreen screen) => HostScreen = screen; - public string UrlPathSegment => "Bar"; - public IScreen HostScreen { get; } - } -} diff --git a/samples/ReactiveUIDemo/ViewModels/FooViewModel.cs b/samples/ReactiveUIDemo/ViewModels/FooViewModel.cs deleted file mode 100644 index 1a363e18dc..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/FooViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class FooViewModel : ReactiveObject, IRoutableViewModel - { - public FooViewModel(IScreen screen) => HostScreen = screen; - public string UrlPathSegment => "Foo"; - public IScreen HostScreen { get; } - } -} diff --git a/samples/ReactiveUIDemo/ViewModels/MainWindowViewModel.cs b/samples/ReactiveUIDemo/ViewModels/MainWindowViewModel.cs deleted file mode 100644 index 2222137d38..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/MainWindowViewModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class MainWindowViewModel : ReactiveObject - { - public RoutedViewHostPageViewModel RoutedViewHost { get; } = new(); - } -} diff --git a/samples/ReactiveUIDemo/ViewModels/RoutedViewHostPageViewModel.cs b/samples/ReactiveUIDemo/ViewModels/RoutedViewHostPageViewModel.cs deleted file mode 100644 index 701447cfe8..0000000000 --- a/samples/ReactiveUIDemo/ViewModels/RoutedViewHostPageViewModel.cs +++ /dev/null @@ -1,21 +0,0 @@ -using ReactiveUI; - -namespace ReactiveUIDemo.ViewModels -{ - internal class RoutedViewHostPageViewModel : ReactiveObject, IScreen - { - public RoutedViewHostPageViewModel() - { - Foo = new(this); - Bar = new(this); - Router.Navigate.Execute(Foo); - } - - public RoutingState Router { get; } = new(); - public FooViewModel Foo { get; } - public BarViewModel Bar { get; } - - public void ShowFoo() => Router.Navigate.Execute(Foo); - public void ShowBar() => Router.Navigate.Execute(Bar); - } -} diff --git a/samples/ReactiveUIDemo/Views/BarView.axaml b/samples/ReactiveUIDemo/Views/BarView.axaml deleted file mode 100644 index 2622245997..0000000000 --- a/samples/ReactiveUIDemo/Views/BarView.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Bar! - - - diff --git a/samples/ReactiveUIDemo/Views/BarView.axaml.cs b/samples/ReactiveUIDemo/Views/BarView.axaml.cs deleted file mode 100644 index 2fbea6de91..0000000000 --- a/samples/ReactiveUIDemo/Views/BarView.axaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using ReactiveUI; -using ReactiveUIDemo.ViewModels; - -namespace ReactiveUIDemo.Views -{ - internal partial class BarView : UserControl, IViewFor - { - public BarView() - { - InitializeComponent(); - } - - public BarViewModel? ViewModel { get; set; } - - object? IViewFor.ViewModel - { - get => ViewModel; - set => ViewModel = (BarViewModel?)value; - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - } -} diff --git a/samples/ReactiveUIDemo/Views/FooView.axaml b/samples/ReactiveUIDemo/Views/FooView.axaml deleted file mode 100644 index 8f73250d3b..0000000000 --- a/samples/ReactiveUIDemo/Views/FooView.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Foo! - - - diff --git a/samples/ReactiveUIDemo/Views/FooView.axaml.cs b/samples/ReactiveUIDemo/Views/FooView.axaml.cs deleted file mode 100644 index 313a71044c..0000000000 --- a/samples/ReactiveUIDemo/Views/FooView.axaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using ReactiveUI; -using ReactiveUIDemo.ViewModels; - -namespace ReactiveUIDemo.Views -{ - internal partial class FooView : UserControl, IViewFor - { - public FooView() - { - InitializeComponent(); - } - - public FooViewModel? ViewModel { get; set; } - - object? IViewFor.ViewModel - { - get => ViewModel; - set => ViewModel = (FooViewModel?)value; - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - } -} diff --git a/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj b/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj index 4dd79dee1b..5d43f20cc4 100644 --- a/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj +++ b/samples/UnloadableAssemblyLoadContext/UnloadableAssemblyLoadContextPlug/UnloadableAssemblyLoadContextPlug.csproj @@ -35,7 +35,6 @@ - diff --git a/src/Avalonia.ReactiveUI/AppBuilderExtensions.cs b/src/Avalonia.ReactiveUI/AppBuilderExtensions.cs deleted file mode 100644 index 3fde580160..0000000000 --- a/src/Avalonia.ReactiveUI/AppBuilderExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Threading; -using ReactiveUI; -using Splat; - -namespace Avalonia.ReactiveUI -{ - public static class AppBuilderExtensions - { - /// - /// Initializes ReactiveUI framework to use with Avalonia. Registers Avalonia - /// scheduler, an activation for view fetcher, a template binding hook. Remember - /// to call this method if you are using ReactiveUI in your application. - /// - public static AppBuilder UseReactiveUI(this AppBuilder builder) => - builder.AfterPlatformServicesSetup(_ => Locator.RegisterResolverCallbackChanged(() => - { - if (Locator.CurrentMutable is null) - { - return; - } - - PlatformRegistrationManager.SetRegistrationNamespaces(RegistrationNamespace.Avalonia); - RxApp.MainThreadScheduler = AvaloniaScheduler.Instance; - Locator.CurrentMutable.RegisterConstant(new AvaloniaActivationForViewFetcher(), typeof(IActivationForViewFetcher)); - Locator.CurrentMutable.RegisterConstant(new AutoDataTemplateBindingHook(), typeof(IPropertyBindingHook)); - })); - } -} diff --git a/src/Avalonia.ReactiveUI/Attributes.cs b/src/Avalonia.ReactiveUI/Attributes.cs deleted file mode 100644 index 1b85cd2f47..0000000000 --- a/src/Avalonia.ReactiveUI/Attributes.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Reflection; -using Avalonia.Metadata; - -[assembly: XmlnsDefinition("http://reactiveui.net", "Avalonia.ReactiveUI")] \ No newline at end of file diff --git a/src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs b/src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs deleted file mode 100644 index b6cdb77f81..0000000000 --- a/src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Linq; -using Avalonia.Controls; -using Avalonia.Controls.Templates; -using Avalonia.Layout; -using Avalonia.Markup.Xaml; -using Avalonia.Markup.Xaml.Templates; -using ReactiveUI; - -namespace Avalonia.ReactiveUI -{ - /// - /// AutoDataTemplateBindingHook is a binding hook that checks ItemsControls - /// that don't have DataTemplates, and assigns a default DataTemplate that - /// loads the View associated with each ViewModel. - /// - public class AutoDataTemplateBindingHook : IPropertyBindingHook - { - private static FuncDataTemplate DefaultItemTemplate = new FuncDataTemplate((x, _) => - { - var control = new ViewModelViewHost(); - var context = control.GetObservable(Control.DataContextProperty); - control.Bind(ViewModelViewHost.ViewModelProperty, context); - control.HorizontalContentAlignment = HorizontalAlignment.Stretch; - control.VerticalContentAlignment = VerticalAlignment.Stretch; - return control; - }, - true); - - /// - public bool ExecuteHook( - object? source, object target, - Func[]> getCurrentViewModelProperties, - Func[]> getCurrentViewProperties, - BindingDirection direction) - { - var viewProperties = getCurrentViewProperties(); - var lastViewProperty = viewProperties.LastOrDefault(); - var itemsControl = lastViewProperty?.Sender as ItemsControl; - if (itemsControl == null) - return true; - - var propertyName = viewProperties.Last().GetPropertyName(); - if (propertyName != "Items" && - propertyName != "ItemsSource") - return true; - - if (itemsControl.ItemTemplate != null) - return true; - - if (itemsControl.DataTemplates != null && - itemsControl.DataTemplates.Count > 0) - return true; - - itemsControl.ItemTemplate = DefaultItemTemplate; - return true; - } - } -} diff --git a/src/Avalonia.ReactiveUI/AutoSuspendHelper.cs b/src/Avalonia.ReactiveUI/AutoSuspendHelper.cs deleted file mode 100644 index ae9a8787bc..0000000000 --- a/src/Avalonia.ReactiveUI/AutoSuspendHelper.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Avalonia; -using Avalonia.VisualTree; -using Avalonia.Controls; -using System.Threading; -using System.Reactive; -using System.Reactive.Disposables; -using System.Reactive.Subjects; -using System.Reactive.Linq; -using ReactiveUI; -using System; -using Avalonia.Controls.ApplicationLifetimes; -using Splat; - -namespace Avalonia.ReactiveUI -{ - /// - /// A ReactiveUI AutoSuspendHelper which initializes suspension hooks for - /// Avalonia applications. Call its constructor in your app's composition root, - /// before calling the RxApp.SuspensionHost.SetupDefaultSuspendResume method. - /// - public sealed class AutoSuspendHelper : IEnableLogger, IDisposable - { - private readonly Subject _shouldPersistState = new Subject(); - private readonly Subject _isLaunchingNew = new Subject(); - - /// - /// Initializes a new instance of the class. - /// - /// Pass in the Application.ApplicationLifetime property. - public AutoSuspendHelper(IApplicationLifetime lifetime) - { - RxApp.SuspensionHost.IsResuming = Observable.Never(); - RxApp.SuspensionHost.IsLaunchingNew = _isLaunchingNew; - - if (Avalonia.Controls.Design.IsDesignMode) - { - this.Log().Debug("Design mode detected. AutoSuspendHelper won't persist app state."); - RxApp.SuspensionHost.ShouldPersistState = Observable.Never(); - } - else if (lifetime is IControlledApplicationLifetime controlled) - { - this.Log().Debug("Using IControlledApplicationLifetime events to handle app exit."); - controlled.Exit += (sender, args) => OnControlledApplicationLifetimeExit(); - RxApp.SuspensionHost.ShouldPersistState = _shouldPersistState; - } - else if (lifetime != null) - { - var type = lifetime.GetType().FullName; - var message = $"Don't know how to detect app exit event for {type}."; - throw new NotSupportedException(message); - } - else - { - var message = "ApplicationLifetime is null. " - + "Ensure you are initializing AutoSuspendHelper " - + "after Avalonia application initialization is completed."; - throw new ArgumentNullException(message); - } - - var errored = new Subject(); - AppDomain.CurrentDomain.UnhandledException += (o, e) => errored.OnNext(Unit.Default); - RxApp.SuspensionHost.ShouldInvalidateState = errored; - } - - /// - /// Call this method in your App.OnFrameworkInitializationCompleted method. - /// - public void OnFrameworkInitializationCompleted() => _isLaunchingNew.OnNext(Unit.Default); - - /// - /// Disposes internally stored observers. - /// - public void Dispose() - { - _shouldPersistState.Dispose(); - _isLaunchingNew.Dispose(); - } - - private void OnControlledApplicationLifetimeExit() - { - this.Log().Debug("Received IControlledApplicationLifetime exit event."); - var manual = new ManualResetEvent(false); - _shouldPersistState.OnNext(Disposable.Create(() => manual.Set())); - - manual.WaitOne(); - this.Log().Debug("Completed actions on IControlledApplicationLifetime exit event."); - } - } -} diff --git a/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj b/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj deleted file mode 100644 index eea1a05d9b..0000000000 --- a/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - $(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0 - false - - - - - - - - - - diff --git a/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs b/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs deleted file mode 100644 index 84048ffd49..0000000000 --- a/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Reactive.Linq; -using Avalonia.VisualTree; -using Avalonia.Controls; -using Avalonia.Interactivity; -using ReactiveUI; - -namespace Avalonia.ReactiveUI -{ - /// - /// Determines when Avalonia IVisuals get activated. - /// - public class AvaloniaActivationForViewFetcher : IActivationForViewFetcher - { - /// - /// Returns affinity for view. - /// - public int GetAffinityForView(Type view) - { - return typeof(Visual).IsAssignableFrom(view) ? 10 : 0; - } - - /// - /// Returns activation observable for activatable Avalonia view. - /// - public IObservable GetActivationForView(IActivatableView view) - { - if (!(view is Visual visual)) return Observable.Return(false); - if (view is Control control) return GetActivationForControl(control); - return GetActivationForVisual(visual); - } - - /// - /// Listens to Loaded and Unloaded - /// events for Avalonia Control. - /// - private IObservable GetActivationForControl(Control control) - { - var controlLoaded = Observable - .FromEventPattern( - x => control.Loaded += x, - x => control.Loaded -= x) - .Select(args => true); - var controlUnloaded = Observable - .FromEventPattern( - x => control.Unloaded += x, - x => control.Unloaded -= x) - .Select(args => false); - return controlLoaded - .Merge(controlUnloaded) - .DistinctUntilChanged(); - } - - /// - /// Listens to AttachedToVisualTree and DetachedFromVisualTree - /// events for Avalonia IVisuals. - /// - private IObservable GetActivationForVisual(Visual visual) - { - var visualLoaded = Observable - .FromEventPattern( - x => visual.AttachedToVisualTree += x, - x => visual.AttachedToVisualTree -= x) - .Select(args => true); - var visualUnloaded = Observable - .FromEventPattern( - x => visual.DetachedFromVisualTree += x, - x => visual.DetachedFromVisualTree -= x) - .Select(args => false); - return visualLoaded - .Merge(visualUnloaded) - .DistinctUntilChanged(); - } - } -} diff --git a/src/Avalonia.ReactiveUI/AvaloniaObjectReactiveExtensions.cs b/src/Avalonia.ReactiveUI/AvaloniaObjectReactiveExtensions.cs deleted file mode 100644 index 4cd329beb6..0000000000 --- a/src/Avalonia.ReactiveUI/AvaloniaObjectReactiveExtensions.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System.Reactive; -using System.Reactive.Subjects; -using Avalonia.Data; - -namespace Avalonia.ReactiveUI; - -public static class AvaloniaObjectReactiveExtensions -{ - /// - /// Gets a subject for an . - /// - /// The object. - /// The property. - /// - /// The priority with which binding values are written to the object. - /// - /// - /// An which can be used for two-way binding to/from the - /// property. - /// - public static ISubject GetSubject( - this AvaloniaObject o, - AvaloniaProperty property, - BindingPriority priority = BindingPriority.LocalValue) - { - return Subject.Create( - Observer.Create(x => o.SetValue(property, x, priority)), - o.GetObservable(property)); - } - - /// - /// Gets a subject for an . - /// - /// The property type. - /// The object. - /// The property. - /// - /// The priority with which binding values are written to the object. - /// - /// - /// An which can be used for two-way binding to/from the - /// property. - /// - public static ISubject GetSubject( - this AvaloniaObject o, - AvaloniaProperty property, - BindingPriority priority = BindingPriority.LocalValue) - { - return Subject.Create( - Observer.Create(x => o.SetValue(property, x, priority)), - o.GetObservable(property)); - } - - /// - /// Gets a subject for a . - /// - /// The object. - /// The property. - /// - /// The priority with which binding values are written to the object. - /// - /// - /// An which can be used for two-way binding to/from the - /// property. - /// - public static ISubject> GetBindingSubject( - this AvaloniaObject o, - AvaloniaProperty property, - BindingPriority priority = BindingPriority.LocalValue) - { - return Subject.Create>( - Observer.Create>(x => - { - if (x.HasValue) - { - o.SetValue(property, x.Value, priority); - } - }), - o.GetBindingObservable(property)); - } - - /// - /// Gets a subject for a . - /// - /// The property type. - /// The object. - /// The property. - /// - /// The priority with which binding values are written to the object. - /// - /// - /// An which can be used for two-way binding to/from the - /// property. - /// - public static ISubject> GetBindingSubject( - this AvaloniaObject o, - AvaloniaProperty property, - BindingPriority priority = BindingPriority.LocalValue) - { - return Subject.Create>( - Observer.Create>(x => - { - if (x.HasValue) - { - o.SetValue(property, x.Value, priority); - } - }), - o.GetBindingObservable(property)); - } -} diff --git a/src/Avalonia.ReactiveUI/AvaloniaScheduler.cs b/src/Avalonia.ReactiveUI/AvaloniaScheduler.cs deleted file mode 100644 index 61c503e7a5..0000000000 --- a/src/Avalonia.ReactiveUI/AvaloniaScheduler.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Reactive.Concurrency; -using System.Reactive.Disposables; -using Avalonia.Threading; - -namespace Avalonia.ReactiveUI -{ - /// - /// A reactive scheduler that uses Avalonia's . - /// - public class AvaloniaScheduler : LocalScheduler - { - /// - /// Users can schedule actions on the dispatcher thread while being on the correct thread already. - /// We are optimizing this case by invoking user callback immediately which can lead to stack overflows in certain cases. - /// To prevent this we are limiting amount of reentrant calls to before we will - /// schedule on a dispatcher anyway. - /// - private const int MaxReentrantSchedules = 32; - - private int _reentrancyGuard; - - /// - /// The instance of the . - /// - public static readonly AvaloniaScheduler Instance = new AvaloniaScheduler(); - - /// - /// Initializes a new instance of the class. - /// - private AvaloniaScheduler() - { - } - - /// - public override IDisposable Schedule(TState state, TimeSpan dueTime, Func action) - { - IDisposable PostOnDispatcher() - { - var composite = new CompositeDisposable(2); - - var cancellation = new CancellationDisposable(); - - Dispatcher.UIThread.Post(() => - { - if (!cancellation.Token.IsCancellationRequested) - { - composite.Add(action(this, state)); - } - }, DispatcherPriority.Background); - - composite.Add(cancellation); - - return composite; - } - - if (dueTime == TimeSpan.Zero) - { - if (!Dispatcher.UIThread.CheckAccess()) - { - return PostOnDispatcher(); - } - else - { - if (_reentrancyGuard >= MaxReentrantSchedules) - { - return PostOnDispatcher(); - } - - try - { - _reentrancyGuard++; - - return action(this, state); - } - finally - { - _reentrancyGuard--; - } - } - } - else - { - var composite = new CompositeDisposable(2); - - composite.Add(DispatcherTimer.RunOnce(() => composite.Add(action(this, state)), dueTime)); - - return composite; - } - } - } -} diff --git a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs deleted file mode 100644 index 76a4f29b16..0000000000 --- a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using Avalonia.Controls; -using ReactiveUI; - -namespace Avalonia.ReactiveUI -{ - /// - /// A ReactiveUI that implements the interface and - /// will activate your ViewModel automatically if the view model implements . - /// When the DataContext property changes, this class will update the ViewModel property with the new DataContext - /// value, and vice versa. - /// - /// ViewModel type. - public class ReactiveUserControl : UserControl, IViewFor where TViewModel : class - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1002", Justification = "Generic avalonia property is expected here.")] - public static readonly StyledProperty ViewModelProperty = AvaloniaProperty - .Register, TViewModel?>(nameof(ViewModel)); - - /// - /// Initializes a new instance of the class. - /// - public ReactiveUserControl() - { - // This WhenActivated block calls ViewModel's WhenActivated - // block if the ViewModel implements IActivatableViewModel. - this.WhenActivated(disposables => { }); - } - - /// - /// The ViewModel. - /// - public TViewModel? ViewModel - { - get => GetValue(ViewModelProperty); - set => SetValue(ViewModelProperty, value); - } - - object? IViewFor.ViewModel - { - get => ViewModel; - set => ViewModel = (TViewModel?)value; - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - - if (change.Property == DataContextProperty) - { - if (ReferenceEquals(change.OldValue, ViewModel) - && change.NewValue is null or TViewModel) - { - SetCurrentValue(ViewModelProperty, change.NewValue); - } - } - else if (change.Property == ViewModelProperty) - { - if (ReferenceEquals(change.OldValue, DataContext)) - { - SetCurrentValue(DataContextProperty, change.NewValue); - } - } - } - } -} diff --git a/src/Avalonia.ReactiveUI/ReactiveWindow.cs b/src/Avalonia.ReactiveUI/ReactiveWindow.cs deleted file mode 100644 index 4048ef1e25..0000000000 --- a/src/Avalonia.ReactiveUI/ReactiveWindow.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using Avalonia.Controls; -using ReactiveUI; - -namespace Avalonia.ReactiveUI -{ - /// - /// A ReactiveUI that implements the interface and will - /// activate your ViewModel automatically if the view model implements . When - /// the DataContext property changes, this class will update the ViewModel property with the new DataContext value, - /// and vice versa. - /// - /// ViewModel type. - public class ReactiveWindow : Window, IViewFor where TViewModel : class - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1002", Justification = "Generic avalonia property is expected here.")] - public static readonly StyledProperty ViewModelProperty = AvaloniaProperty - .Register, TViewModel?>(nameof(ViewModel)); - - /// - /// Initializes a new instance of the class. - /// - public ReactiveWindow() - { - // This WhenActivated block calls ViewModel's WhenActivated - // block if the ViewModel implements IActivatableViewModel. - this.WhenActivated(disposables => { }); - } - - /// - /// The ViewModel. - /// - public TViewModel? ViewModel - { - get => GetValue(ViewModelProperty); - set => SetValue(ViewModelProperty, value); - } - - object? IViewFor.ViewModel - { - get => ViewModel; - set => ViewModel = (TViewModel?)value; - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - - if (change.Property == DataContextProperty) - { - if (ReferenceEquals(change.OldValue, ViewModel) - && change.NewValue is null or TViewModel) - { - SetCurrentValue(ViewModelProperty, change.NewValue); - } - } - else if (change.Property == ViewModelProperty) - { - if (ReferenceEquals(change.OldValue, DataContext)) - { - SetCurrentValue(DataContextProperty, change.NewValue); - } - } - } - } -} diff --git a/src/Avalonia.ReactiveUI/RoutedViewHost.cs b/src/Avalonia.ReactiveUI/RoutedViewHost.cs deleted file mode 100644 index 701b0d0f46..0000000000 --- a/src/Avalonia.ReactiveUI/RoutedViewHost.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Avalonia.Animation; -using Avalonia.Controls; -using Avalonia.Styling; -using Avalonia; -using ReactiveUI; -using Splat; - -namespace Avalonia.ReactiveUI -{ - /// - /// This control hosts the View associated with ReactiveUI RoutingState, - /// and will display the View and wire up the ViewModel whenever a new - /// ViewModel is navigated to. Nested routing is also supported. - /// - /// - /// - /// ReactiveUI routing consists of an IScreen that contains current - /// RoutingState, several IRoutableViewModels, and a platform-specific - /// XAML control called RoutedViewHost. - /// - /// - /// RoutingState manages the ViewModel navigation stack and allows - /// ViewModels to navigate to other ViewModels. IScreen is the root of - /// a navigation stack; despite the name, its views don't have to occupy - /// the whole screen. RoutedViewHost monitors an instance of RoutingState, - /// responding to any changes in the navigation stack by creating and - /// embedding the appropriate view. - /// - /// - /// Place this control to a view containing your ViewModel that implements - /// IScreen, and bind IScreen.Router property to RoutedViewHost.Router property. - /// - /// - /// - /// - /// - /// - /// ]]> - /// - /// - /// - /// See - /// ReactiveUI routing documentation website for more info. - /// - /// - public class RoutedViewHost : TransitioningContentControl, IActivatableView, IEnableLogger - { - /// - /// for the property. - /// - public static readonly StyledProperty RouterProperty = - AvaloniaProperty.Register(nameof(Router)); - - /// - /// for the property. - /// - public static readonly StyledProperty ViewContractProperty = - AvaloniaProperty.Register(nameof(ViewContract)); - - /// - /// for the property. - /// - public static readonly StyledProperty DefaultContentProperty = - ViewModelViewHost.DefaultContentProperty.AddOwner(); - - /// - /// Initializes a new instance of the class. - /// - public RoutedViewHost() - { - this.WhenActivated(disposables => - { - var routerRemoved = this - .WhenAnyValue(x => x.Router) - .Where(router => router == null)! - .Cast(); - - var viewContract = this.WhenAnyValue(x => x.ViewContract); - - this.WhenAnyValue(x => x.Router) - .Where(router => router != null) - .SelectMany(router => router!.CurrentViewModel) - .Merge(routerRemoved) - .CombineLatest(viewContract) - .Subscribe(tuple => NavigateToViewModel(tuple.First, tuple.Second)) - .DisposeWith(disposables); - }); - } - - /// - /// Gets or sets the of the view model stack. - /// - public RoutingState? Router - { - get => GetValue(RouterProperty); - set => SetValue(RouterProperty, value); - } - - /// - /// Gets or sets the view contract. - /// - public string? ViewContract - { - get => GetValue(ViewContractProperty); - set => SetValue(ViewContractProperty, value); - } - - /// - /// Gets or sets the content displayed whenever there is no page currently routed. - /// - public object? DefaultContent - { - get => GetValue(DefaultContentProperty); - set => SetValue(DefaultContentProperty, value); - } - - /// - /// Gets or sets the ReactiveUI view locator used by this router. - /// - public IViewLocator? ViewLocator { get; set; } - - protected override Type StyleKeyOverride => typeof(TransitioningContentControl); - - /// - /// Invoked when ReactiveUI router navigates to a view model. - /// - /// ViewModel to which the user navigates. - /// The contract for view resolution. - private void NavigateToViewModel(object? viewModel, string? contract) - { - if (Router == null) - { - this.Log().Warn("Router property is null. Falling back to default content."); - Content = DefaultContent; - return; - } - - if (viewModel == null) - { - this.Log().Info("ViewModel is null. Falling back to default content."); - Content = DefaultContent; - return; - } - - var viewLocator = ViewLocator ?? global::ReactiveUI.ViewLocator.Current; - var viewInstance = viewLocator.ResolveView(viewModel, contract); - if (viewInstance == null) - { - if (contract == null) - { - this.Log().Warn($"Couldn't find view for '{viewModel}'. Is it registered? Falling back to default content."); - } - else - { - this.Log().Warn($"Couldn't find view with contract '{contract}' for '{viewModel}'. Is it registered? Falling back to default content."); - } - - Content = DefaultContent; - return; - } - - if (contract == null) - { - this.Log().Info($"Ready to show {viewInstance} with autowired {viewModel}."); - } - else - { - this.Log().Info($"Ready to show {viewInstance} with autowired {viewModel} and contract '{contract}'."); - } - - viewInstance.ViewModel = viewModel; - if (viewInstance is IDataContextProvider provider) - provider.DataContext = viewModel; - Content = viewInstance; - } - } -} diff --git a/src/Avalonia.ReactiveUI/ViewModelViewHost.cs b/src/Avalonia.ReactiveUI/ViewModelViewHost.cs deleted file mode 100644 index 3e7ed42662..0000000000 --- a/src/Avalonia.ReactiveUI/ViewModelViewHost.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Reactive.Disposables; - -using Avalonia.Controls; -using Avalonia.Styling; -using ReactiveUI; -using Splat; - -namespace Avalonia.ReactiveUI -{ - /// - /// This content control will automatically load the View associated with - /// the ViewModel property and display it. This control is very useful - /// inside a DataTemplate to display the View associated with a ViewModel. - /// - public class ViewModelViewHost : TransitioningContentControl, IViewFor, IEnableLogger - { - /// - /// for the property. - /// - public static readonly AvaloniaProperty ViewModelProperty = - AvaloniaProperty.Register(nameof(ViewModel)); - - /// - /// for the property. - /// - public static readonly StyledProperty ViewContractProperty = - AvaloniaProperty.Register(nameof(ViewContract)); - - /// - /// for the property. - /// - public static readonly StyledProperty DefaultContentProperty = - AvaloniaProperty.Register(nameof(DefaultContent)); - - /// - /// Initializes a new instance of the class. - /// - public ViewModelViewHost() - { - this.WhenActivated(disposables => - { - this.WhenAnyValue(x => x.ViewModel, x => x.ViewContract) - .Subscribe(tuple => NavigateToViewModel(tuple.Item1, tuple.Item2)) - .DisposeWith(disposables); - }); - } - - /// - /// Gets or sets the ViewModel to display. - /// - public object? ViewModel - { - get => GetValue(ViewModelProperty); - set => SetValue(ViewModelProperty, value); - } - - /// - /// Gets or sets the view contract. - /// - public string? ViewContract - { - get => GetValue(ViewContractProperty); - set => SetValue(ViewContractProperty, value); - } - - /// - /// Gets or sets the content displayed whenever there is no page currently routed. - /// - public object? DefaultContent - { - get => GetValue(DefaultContentProperty); - set => SetValue(DefaultContentProperty, value); - } - - /// - /// Gets or sets the view locator. - /// - public IViewLocator? ViewLocator { get; set; } - - protected override Type StyleKeyOverride => typeof(TransitioningContentControl); - - /// - /// Invoked when ReactiveUI router navigates to a view model. - /// - /// ViewModel to which the user navigates. - /// The contract for view resolution. - private void NavigateToViewModel(object? viewModel, string? contract) - { - if (viewModel == null) - { - this.Log().Info("ViewModel is null. Falling back to default content."); - Content = DefaultContent; - return; - } - - var viewLocator = ViewLocator ?? global::ReactiveUI.ViewLocator.Current; - var viewInstance = viewLocator.ResolveView(viewModel, contract); - if (viewInstance == null) - { - if (contract == null) - { - this.Log().Warn($"Couldn't find view for '{viewModel}'. Is it registered? Falling back to default content."); - } - else - { - this.Log().Warn($"Couldn't find view with contract '{contract}' for '{viewModel}'. Is it registered? Falling back to default content."); - } - - Content = DefaultContent; - return; - } - - if (contract == null) - { - this.Log().Info($"Ready to show {viewInstance} with autowired {viewModel}."); - } - else - { - this.Log().Info($"Ready to show {viewInstance} with autowired {viewModel} and contract '{contract}'."); - } - - viewInstance.ViewModel = viewModel; - if (viewInstance is StyledElement styled) - styled.DataContext = viewModel; - Content = viewInstance; - } - } -} diff --git a/tests/Avalonia.Generators.Tests/Avalonia.Generators.Tests.csproj b/tests/Avalonia.Generators.Tests/Avalonia.Generators.Tests.csproj index 7270a54c25..a32303dcfa 100644 --- a/tests/Avalonia.Generators.Tests/Avalonia.Generators.Tests.csproj +++ b/tests/Avalonia.Generators.Tests/Avalonia.Generators.Tests.csproj @@ -8,7 +8,6 @@ - diff --git a/tests/Avalonia.Generators.Tests/InitializeComponent/GeneratedInitializeComponent/CustomControls.txt b/tests/Avalonia.Generators.Tests/InitializeComponent/GeneratedInitializeComponent/CustomControls.txt index 5911e30e56..cc001898e3 100644 --- a/tests/Avalonia.Generators.Tests/InitializeComponent/GeneratedInitializeComponent/CustomControls.txt +++ b/tests/Avalonia.Generators.Tests/InitializeComponent/GeneratedInitializeComponent/CustomControls.txt @@ -9,9 +9,9 @@ namespace Sample.App partial class SampleView { [global::System.CodeDom.Compiler.GeneratedCode("Avalonia.Generators.NameGenerator.InitializeComponentCodeGenerator", "$GeneratorVersion")] - internal global::Avalonia.ReactiveUI.RoutedViewHost ClrNamespaceRoutedViewHost; + internal global::Avalonia.Controls.ColorPicker ClrNamespaceColorPicker; [global::System.CodeDom.Compiler.GeneratedCode("Avalonia.Generators.NameGenerator.InitializeComponentCodeGenerator", "$GeneratorVersion")] - internal global::Avalonia.ReactiveUI.RoutedViewHost UriRoutedViewHost; + internal global::Avalonia.Controls.ColorPicker UriColorPicker; [global::System.CodeDom.Compiler.GeneratedCode("Avalonia.Generators.NameGenerator.InitializeComponentCodeGenerator", "$GeneratorVersion")] internal global::Controls.CustomTextBox UserNameTextBox; @@ -30,8 +30,8 @@ namespace Sample.App } var __thisNameScope__ = this.FindNameScope(); - ClrNamespaceRoutedViewHost = __thisNameScope__?.Find("ClrNamespaceRoutedViewHost"); - UriRoutedViewHost = __thisNameScope__?.Find("UriRoutedViewHost"); + ClrNamespaceColorPicker = __thisNameScope__?.Find("ClrNamespaceColorPicker"); + UriColorPicker = __thisNameScope__?.Find("UriColorPicker"); UserNameTextBox = __thisNameScope__?.Find("UserNameTextBox"); } } diff --git a/tests/Avalonia.Generators.Tests/OnlyProperties/GeneratedCode/CustomControls.txt b/tests/Avalonia.Generators.Tests/OnlyProperties/GeneratedCode/CustomControls.txt index 46175e85ef..1d7d25f5bb 100644 --- a/tests/Avalonia.Generators.Tests/OnlyProperties/GeneratedCode/CustomControls.txt +++ b/tests/Avalonia.Generators.Tests/OnlyProperties/GeneratedCode/CustomControls.txt @@ -7,9 +7,9 @@ namespace Sample.App partial class SampleView { [global::System.CodeDom.Compiler.GeneratedCode("Avalonia.Generators.NameGenerator.OnlyPropertiesCodeGenerator", "$GeneratorVersion")] - internal global::Avalonia.ReactiveUI.RoutedViewHost ClrNamespaceRoutedViewHost => this.FindNameScope()?.Find("ClrNamespaceRoutedViewHost"); + internal global::Avalonia.Controls.ColorPicker ClrNamespaceColorPicker => this.FindNameScope()?.Find("ClrNamespaceColorPicker"); [global::System.CodeDom.Compiler.GeneratedCode("Avalonia.Generators.NameGenerator.OnlyPropertiesCodeGenerator", "$GeneratorVersion")] - internal global::Avalonia.ReactiveUI.RoutedViewHost UriRoutedViewHost => this.FindNameScope()?.Find("UriRoutedViewHost"); + internal global::Avalonia.Controls.ColorPicker UriColorPicker => this.FindNameScope()?.Find("UriColorPicker"); [global::System.CodeDom.Compiler.GeneratedCode("Avalonia.Generators.NameGenerator.OnlyPropertiesCodeGenerator", "$GeneratorVersion")] internal global::Controls.CustomTextBox UserNameTextBox => this.FindNameScope()?.Find("UserNameTextBox"); } diff --git a/tests/Avalonia.Generators.Tests/Views/AttachedProps.xml b/tests/Avalonia.Generators.Tests/Views/AttachedProps.xml index 896da6d1cd..209b7ca9f1 100644 --- a/tests/Avalonia.Generators.Tests/Views/AttachedProps.xml +++ b/tests/Avalonia.Generators.Tests/Views/AttachedProps.xml @@ -1,10 +1,8 @@  - \ No newline at end of file + diff --git a/tests/Avalonia.Generators.Tests/Views/ControlWithoutWindow.xml b/tests/Avalonia.Generators.Tests/Views/ControlWithoutWindow.xml index 77de06a27e..485fe93e4c 100644 --- a/tests/Avalonia.Generators.Tests/Views/ControlWithoutWindow.xml +++ b/tests/Avalonia.Generators.Tests/Views/ControlWithoutWindow.xml @@ -1,10 +1,8 @@  - \ No newline at end of file + diff --git a/tests/Avalonia.Generators.Tests/Views/CustomControls.xml b/tests/Avalonia.Generators.Tests/Views/CustomControls.xml index 9085e73d4b..d139e44f6e 100644 --- a/tests/Avalonia.Generators.Tests/Views/CustomControls.xml +++ b/tests/Avalonia.Generators.Tests/Views/CustomControls.xml @@ -1,11 +1,11 @@  - - + xmlns:av="https://github.com/avaloniaui"> + + - \ No newline at end of file + diff --git a/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs b/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs index 5af5ba4b00..0cd47fe2a8 100644 --- a/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs +++ b/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs @@ -6,9 +6,7 @@ using Avalonia.Controls; using Avalonia.Generators.Common; using Avalonia.Generators.Common.Domain; using Avalonia.Generators.Compiler; -using Avalonia.ReactiveUI; using Avalonia.Generators.Tests.Views; -using Microsoft.CodeAnalysis; using Xunit; namespace Avalonia.Generators.Tests; @@ -56,11 +54,11 @@ public class XamlXNameResolverTests Assert.NotEmpty(controls); Assert.Equal(3, controls.Count); - Assert.Equal("ClrNamespaceRoutedViewHost", controls[0].Name); - Assert.Equal("UriRoutedViewHost", controls[1].Name); + Assert.Equal("ClrNamespaceColorPicker", controls[0].Name); + Assert.Equal("UriColorPicker", controls[1].Name); Assert.Equal("UserNameTextBox", controls[2].Name); - Assert.Contains(typeof(RoutedViewHost).FullName!, controls[0].TypeName); - Assert.Contains(typeof(RoutedViewHost).FullName!, controls[1].TypeName); + Assert.Contains(typeof(ColorPicker).FullName!, controls[0].TypeName); + Assert.Contains(typeof(ColorPicker).FullName!, controls[1].TypeName); Assert.Contains("Controls.CustomTextBox", controls[2].TypeName); } diff --git a/tests/Avalonia.ReactiveUI.UnitTests/Attributes.cs b/tests/Avalonia.ReactiveUI.UnitTests/Attributes.cs deleted file mode 100644 index 6d0d1f0488..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/Attributes.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Avalonia.UnitTests; -using Xunit; - -// Required to avoid InvalidOperationException sometimes thrown -// from Splat.MemoizingMRUCache.cs which is not thread-safe. -// Thrown when trying to access WhenActivated concurrently. -[assembly: CollectionBehavior(DisableTestParallelization = true)] -[assembly: VerifyEmptyDispatcherAfterTest] diff --git a/tests/Avalonia.ReactiveUI.UnitTests/AutoDataTemplateBindingHookTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/AutoDataTemplateBindingHookTest.cs deleted file mode 100644 index 9f49d94801..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/AutoDataTemplateBindingHookTest.cs +++ /dev/null @@ -1,146 +0,0 @@ -using Xunit; -using ReactiveUI; -using Avalonia.ReactiveUI; -using Avalonia.UnitTests; -using Avalonia.Controls; -using Avalonia.Controls.Templates; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Avalonia.VisualTree; -using Avalonia.Controls.Presenters; -using Splat; -using System.Threading.Tasks; -using System; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class AutoDataTemplateBindingHookTest - { - public class NestedViewModel : ReactiveObject { } - - public class NestedView : ReactiveUserControl { } - - public class ExampleViewModel : ReactiveObject - { - public ObservableCollection Items { get; } = new ObservableCollection(); - } - - public class ExampleView : ReactiveUserControl - { - public ItemsControl List { get; } = new ItemsControl - { - Template = GetTemplate() - }; - - public ExampleView(Action adjustItemsControl = null) - { - adjustItemsControl?.Invoke(List); - List.ApplyTemplate(); - List.Presenter.ApplyTemplate(); - - Content = List; - ViewModel = new ExampleViewModel(); - this.OneWayBind(ViewModel, x => x.Items, x => x.List.ItemsSource); - } - } - - public AutoDataTemplateBindingHookTest() - { - Locator.CurrentMutable.RegisterConstant(new AutoDataTemplateBindingHook(), typeof(IPropertyBindingHook)); - Locator.CurrentMutable.RegisterConstant(new AvaloniaActivationForViewFetcher(), typeof(IActivationForViewFetcher)); - Locator.CurrentMutable.Register(() => new NestedView(), typeof(IViewFor)); - } - - [Fact] - public void Should_Apply_Data_Template_Binding_When_No_Template_Is_Set() - { - var view = new ExampleView(); - Assert.NotNull(view.List.ItemTemplate); - Assert.IsType>(view.List.ItemTemplate); - } - - [Fact] - public void Should_Use_ViewModelViewHost_As_Data_Template_By_Default() - { - var view = new ExampleView(); - view.ViewModel.Items.Add(new NestedViewModel()); - - var child = view.List.Presenter.Panel.Children[0]; - var container = (ContentPresenter) child; - container.UpdateChild(); - - Assert.IsType(container.Child); - } - - [Fact] - public void ViewModelViewHost_Should_Resolve_And_Embedd_Appropriate_View_Model() - { - var view = new ExampleView(); - view.ViewModel.Items.Add(new NestedViewModel()); - - var child = view.List.Presenter.Panel.Children[0]; - var container = (ContentPresenter) child; - container.UpdateChild(); - - var host = (ViewModelViewHost) container.Child; - Assert.IsType(host.ViewModel); - Assert.IsType(host.DataContext); - - host.DataContext = "changed context"; - Assert.IsType(host.ViewModel); - Assert.IsType(host.DataContext); - } - - [Fact] - public void Should_Not_Override_Data_Template_Binding_When_Item_Template_Is_Set() - { - var view = new ExampleView(control => control.ItemTemplate = GetItemTemplate()); - Assert.NotNull(view.List.ItemTemplate); - Assert.IsType>(view.List.ItemTemplate); - } - - [Fact] - public void Should_Not_Use_View_Model_View_Host_When_Item_Template_Is_Set() - { - var view = new ExampleView(control => control.ItemTemplate = GetItemTemplate()); - view.ViewModel.Items.Add(new NestedViewModel()); - - var child = view.List.Presenter.Panel.Children[0]; - var container = (ContentPresenter) child; - container.UpdateChild(); - - Assert.IsType(container.Child); - } - - [Fact] - public void Should_Not_Use_View_Model_View_Host_When_Data_Templates_Are_Not_Empty() - { - var view = new ExampleView(control => control.DataTemplates.Add(GetItemTemplate())); - view.ViewModel.Items.Add(new NestedViewModel()); - - var child = view.List.Presenter.Panel.Children[0]; - var container = (ContentPresenter) child; - container.UpdateChild(); - - Assert.IsType(container.Child); - } - - private static FuncDataTemplate GetItemTemplate() - { - return new FuncDataTemplate((parent, scope) => new TextBlock()); - } - - private static FuncControlTemplate GetTemplate() - { - return new FuncControlTemplate((parent, scope) => new Border - { - Background = new Media.SolidColorBrush(0xffffffff), - Child = new ItemsPresenter - { - Name = "PART_ItemsPresenter", - }.RegisterInNameScope(scope) - }); - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/AutoSuspendHelperTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/AutoSuspendHelperTest.cs deleted file mode 100644 index 30326adba5..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/AutoSuspendHelperTest.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Reactive.Concurrency; -using System.Reactive.Disposables; -using System.ComponentModel; -using System.Threading.Tasks; -using System.Reactive; -using System.Reactive.Subjects; -using System.Reactive.Linq; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Threading; -using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Controls; -using Avalonia.Rendering; -using Avalonia.Platform; -using Avalonia.UnitTests; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; -using Avalonia; -using Avalonia.Threading; -using ReactiveUI; -using DynamicData; -using Xunit; -using Splat; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class AutoSuspendHelperTest - { - [DataContract] - public class AppState - { - [DataMember] - public string Example { get; set; } - } - - public class ExoticApplicationLifetimeWithoutLifecycleEvents : IDisposable, IApplicationLifetime - { - public void Dispose() { } - } - - [Fact] - public void AutoSuspendHelper_Should_Immediately_Fire_IsLaunchingNew() - { - using (UnitTestApplication.Start(TestServices.MockWindowingPlatform)) - using (var lifetime = new ClassicDesktopStyleApplicationLifetime()) - { - var isLaunchingReceived = false; - var application = AvaloniaLocator.Current.GetRequiredService(); - application.ApplicationLifetime = lifetime; - - // Initialize ReactiveUI Suspension as in real-world scenario. - var suspension = new AutoSuspendHelper(application.ApplicationLifetime); - RxApp.SuspensionHost.IsLaunchingNew.Subscribe(_ => isLaunchingReceived = true); - suspension.OnFrameworkInitializationCompleted(); - - Assert.True(isLaunchingReceived); - } - } - - [Fact] - public void AutoSuspendHelper_Should_Throw_When_Not_Supported_Lifetime_Is_Used() - { - using (UnitTestApplication.Start(TestServices.MockWindowingPlatform)) - using (var lifetime = new ExoticApplicationLifetimeWithoutLifecycleEvents()) - { - var application = AvaloniaLocator.Current.GetRequiredService(); - application.ApplicationLifetime = lifetime; - Assert.Throws(() => new AutoSuspendHelper(application.ApplicationLifetime)); - } - } - - [Fact] - public void AutoSuspendHelper_Should_Throw_When_Lifetime_Is_Null() - { - using (UnitTestApplication.Start(TestServices.MockWindowingPlatform)) - { - var application = AvaloniaLocator.Current.GetService(); - Assert.Throws(() => new AutoSuspendHelper(application.ApplicationLifetime)); - } - } - - [Fact] - public void ShouldPersistState_Should_Fire_On_App_Exit_When_SuspensionDriver_Is_Initialized() - { - using (UnitTestApplication.Start(TestServices.MockWindowingPlatform)) - using (var lifetime = new ClassicDesktopStyleApplicationLifetime()) - { - var shouldPersistReceived = false; - var application = AvaloniaLocator.Current.GetRequiredService(); - application.ApplicationLifetime = lifetime; - - // Initialize ReactiveUI Suspension as in real-world scenario. - var suspension = new AutoSuspendHelper(application.ApplicationLifetime); - RxApp.SuspensionHost.CreateNewAppState = () => new AppState { Example = "Foo" }; - RxApp.SuspensionHost.ShouldPersistState.Subscribe(_ => shouldPersistReceived = true); - RxApp.SuspensionHost.SetupDefaultSuspendResume(new FakeSuspensionDriver()); - suspension.OnFrameworkInitializationCompleted(); - - lifetime.Shutdown(); - - Assert.True(shouldPersistReceived); - Assert.Equal("Foo", RxApp.SuspensionHost.GetAppState().Example); - } - } - - private class FakeSuspensionDriver : ISuspensionDriver - { - public IObservable LoadState() => Observable.Empty(); - - public IObservable SaveState(object state) => Observable.Empty(); - - public IObservable InvalidateState() => Observable.Empty(); - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/Avalonia.ReactiveUI.UnitTests.csproj b/tests/Avalonia.ReactiveUI.UnitTests/Avalonia.ReactiveUI.UnitTests.csproj deleted file mode 100644 index 3475b0788e..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/Avalonia.ReactiveUI.UnitTests.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - $(AvsCurrentTargetFramework) - false - - - - - - - - - - - - diff --git a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs deleted file mode 100644 index c25816040a..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Reactive.Concurrency; -using System.Reactive.Disposables; -using Avalonia.Controls; -using Avalonia.Rendering; -using Avalonia.Platform; -using Avalonia.UnitTests; -using Avalonia; -using ReactiveUI; -using DynamicData; -using Xunit; -using Splat; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; -using Avalonia.Threading; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class AvaloniaActivationForViewFetcherTest - { - public class TestUserControl : UserControl, IActivatableView { } - - public class TestUserControlWithWhenActivated : UserControl, IActivatableView - { - public bool Active { get; private set; } - - public TestUserControlWithWhenActivated() - { - this.WhenActivated(disposables => - { - Active = true; - Disposable - .Create(() => Active = false) - .DisposeWith(disposables); - }); - } - } - - public class TestWindowWithWhenActivated : Window, IActivatableView - { - public bool Active { get; private set; } - - public TestWindowWithWhenActivated() - { - this.WhenActivated(disposables => - { - Active = true; - Disposable - .Create(() => Active = false) - .DisposeWith(disposables); - }); - } - } - - public class ActivatableViewModel : IActivatableViewModel - { - public ViewModelActivator Activator { get; } - - public bool IsActivated { get; private set; } - - public ActivatableViewModel() - { - Activator = new ViewModelActivator(); - this.WhenActivated(disposables => - { - IsActivated = true; - Disposable - .Create(() => IsActivated = false) - .DisposeWith(disposables); - }); - } - } - - public class ActivatableWindow : ReactiveWindow - { - public ActivatableWindow() - { - Content = new Border(); - this.WhenActivated(disposables => { }); - } - } - - public class ActivatableUserControl : ReactiveUserControl - { - public ActivatableUserControl() - { - Content = new Border(); - this.WhenActivated(disposables => { }); - } - } - - public AvaloniaActivationForViewFetcherTest() => - Locator - .CurrentMutable - .RegisterConstant( - new AvaloniaActivationForViewFetcher(), - typeof(IActivationForViewFetcher)); - - [Fact] - public void Visual_Element_Is_Activated_And_Deactivated() - { - var userControl = new TestUserControl(); - var activationForViewFetcher = new AvaloniaActivationForViewFetcher(); - - activationForViewFetcher - .GetActivationForView(userControl) - .ToObservableChangeSet(scheduler: ImmediateScheduler.Instance) - .Bind(out var activated) - .Subscribe(); - - var fakeRenderedDecorator = new TestRoot(); - fakeRenderedDecorator.Child = userControl; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.True(activated[0]); - Assert.Equal(1, activated.Count); - - fakeRenderedDecorator.Child = null; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.True(activated[0]); - Assert.False(activated[1]); - Assert.Equal(2, activated.Count); - } - - [Fact] - public void Get_Affinity_For_View_Should_Return_Non_Zero_For_Visual_Elements() - { - var userControl = new TestUserControl(); - var activationForViewFetcher = new AvaloniaActivationForViewFetcher(); - - var forUserControl = activationForViewFetcher.GetAffinityForView(userControl.GetType()); - var forNonUserControl = activationForViewFetcher.GetAffinityForView(typeof(object)); - - Assert.NotEqual(0, forUserControl); - Assert.Equal(0, forNonUserControl); - } - - [Fact] - public void Activation_For_View_Fetcher_Should_Support_When_Activated() - { - var userControl = new TestUserControlWithWhenActivated(); - Assert.False(userControl.Active); - - var fakeRenderedDecorator = new TestRoot(); - fakeRenderedDecorator.Child = userControl; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.True(userControl.Active); - - fakeRenderedDecorator.Child = null; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.False(userControl.Active); - } - - [Fact] - public void Activation_For_View_Fetcher_Should_Support_Windows() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var window = new TestWindowWithWhenActivated(); - Assert.False(window.Active); - - window.Show(); - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.True(window.Active); - - window.Close(); - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.False(window.Active); - } - } - - [Fact] - public void Activatable_Window_View_Model_Is_Activated_And_Deactivated() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var viewModel = new ActivatableViewModel(); - var window = new ActivatableWindow { ViewModel = viewModel }; - Assert.False(viewModel.IsActivated); - - window.Show(); - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.True(viewModel.IsActivated); - - window.Close(); - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.False(viewModel.IsActivated); - } - } - - [Fact] - public void Activatable_User_Control_View_Model_Is_Activated_And_Deactivated() - { - var root = new TestRoot(); - var viewModel = new ActivatableViewModel(); - var control = new ActivatableUserControl { ViewModel = viewModel }; - Assert.False(viewModel.IsActivated); - - root.Child = control; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.True(viewModel.IsActivated); - - root.Child = null; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.False(viewModel.IsActivated); - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaObjectTests_GetSubject.cs b/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaObjectTests_GetSubject.cs deleted file mode 100644 index 4cfe8e9804..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaObjectTests_GetSubject.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using Xunit; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class AvaloniaObjectTests_GetSubject - { - [Fact] - public void GetSubject_Returns_Values() - { - var source = new Class1 { Foo = "foo" }; - var target = source.GetSubject(Class1.FooProperty); - var result = new List(); - - target.Subscribe(x => result.Add(x)); - source.Foo = "bar"; - source.Foo = "baz"; - - Assert.Equal(new[] { "foo", "bar", "baz" }, result); - } - - [Fact] - public void GetSubject_Sets_Values() - { - var source = new Class1 { Foo = "foo" }; - var target = source.GetSubject(Class1.FooProperty); - - target.OnNext("bar"); - Assert.Equal("bar", source.Foo); - } - - private class Class1 : AvaloniaObject - { - public static readonly StyledProperty FooProperty = - AvaloniaProperty.Register(nameof(Foo), "foodefault"); - - public string Foo - { - get => GetValue(FooProperty); - set => SetValue(FooProperty, value); - } - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs deleted file mode 100644 index d744f2ccac..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System.Reactive.Disposables; -using Avalonia.Controls; -using Avalonia.Threading; -using Avalonia.UnitTests; -using ReactiveUI; -using Splat; -using Xunit; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class ReactiveUserControlTest : ScopedTestBase - { - public class ExampleViewModel : ReactiveObject, IActivatableViewModel - { - public bool IsActive { get; private set; } - - public ViewModelActivator Activator { get; } = new ViewModelActivator(); - - public ExampleViewModel() => this.WhenActivated(disposables => - { - IsActive = true; - Disposable - .Create(() => IsActive = false) - .DisposeWith(disposables); - }); - } - - public class ExampleView : ReactiveUserControl { } - - public ReactiveUserControlTest() => - Locator - .CurrentMutable - .RegisterConstant( - new AvaloniaActivationForViewFetcher(), - typeof(IActivationForViewFetcher)); - - [Fact] - public void Data_Context_Should_Stay_In_Sync_With_Reactive_User_Control_View_Model() - { - var root = new TestRoot(); - var view = new ExampleView(); - root.Child = view; - - var viewModel = new ExampleViewModel(); - Assert.Null(view.ViewModel); - - view.DataContext = viewModel; - Assert.Equal(view.ViewModel, viewModel); - Assert.Equal(view.DataContext, viewModel); - - view.DataContext = null; - Assert.Null(view.ViewModel); - Assert.Null(view.DataContext); - - view.ViewModel = viewModel; - Assert.Equal(viewModel, view.ViewModel); - Assert.Equal(viewModel, view.DataContext); - - view.ViewModel = null; - Assert.Null(view.ViewModel); - Assert.Null(view.DataContext); - } - - [Fact] - public void Should_Start_With_NotNull_Activated_ViewModel() - { - var root = new TestRoot(); - var view = new ExampleView {ViewModel = new ExampleViewModel()}; - - Assert.False(view.ViewModel.IsActive); - - root.Child = view; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.True(view.ViewModel.IsActive); - - root.Child = null; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.False(view.ViewModel.IsActive); - } - - [Fact] - public void Should_Start_With_NotNull_Activated_DataContext() - { - var root = new TestRoot(); - var view = new ExampleView {DataContext = new ExampleViewModel()}; - - Assert.False(view.ViewModel.IsActive); - - root.Child = view; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.True(view.ViewModel.IsActive); - - root.Child = null; - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.False(view.ViewModel.IsActive); - } - - [Fact] - public void Should_Inherit_DataContext() - { - var vm1 = new ExampleViewModel(); - var vm2 = new ExampleViewModel(); - var view = new ExampleView(); - var root = new TestRoot(view); - - Assert.Null(view.DataContext); - Assert.Null(view.ViewModel); - - root.DataContext = vm1; - - Assert.Same(vm1, view.DataContext); - Assert.Same(vm1, view.ViewModel); - - root.DataContext = null; - - Assert.Null(view.DataContext); - Assert.Null(view.ViewModel); - - root.DataContext = vm2; - - Assert.Same(vm2, view.DataContext); - Assert.Same(vm2, view.ViewModel); - } - - // https://github.com/AvaloniaUI/Avalonia/issues/15060 - [Fact] - public void Should_Not_Inherit_DataContext_Of_Wrong_Type() - { - var view = new ExampleView(); - var root = new TestRoot(view); - - Assert.Null(view.DataContext); - Assert.Null(view.ViewModel); - - root.DataContext = this; - - Assert.Same(this, view.DataContext); - Assert.Null(view.ViewModel); - } - - [Fact] - public void Should_Not_Overlap_Change_Notifications() - { - var vm1 = new ExampleViewModel(); - var vm2 = new ExampleViewModel(); - - var view1 = new ExampleView(); - var view2 = new ExampleView(); - - Assert.Null(view1.DataContext); - Assert.Null(view2.DataContext); - Assert.Null(view1.ViewModel); - Assert.Null(view2.ViewModel); - - view1.DataContext = vm1; - - Assert.Same(vm1, view1.DataContext); - Assert.Same(vm1, view1.ViewModel); - Assert.Null(view2.DataContext); - Assert.Null(view2.ViewModel); - - view2.DataContext = vm2; - - Assert.Same(vm1, view1.DataContext); - Assert.Same(vm1, view1.ViewModel); - Assert.Same(vm2, view2.DataContext); - Assert.Same(vm2, view2.ViewModel); - - view1.ViewModel = null; - - Assert.Null(view1.DataContext); - Assert.Null(view1.ViewModel); - Assert.Same(vm2, view2.DataContext); - Assert.Same(vm2, view2.ViewModel); - - view2.ViewModel = null; - - Assert.Null(view1.DataContext); - Assert.Null(view2.DataContext); - Assert.Null(view1.ViewModel); - Assert.Null(view2.ViewModel); - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs deleted file mode 100644 index a71a500ed9..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Reactive.Disposables; -using Avalonia.Threading; -using Avalonia.UnitTests; -using ReactiveUI; -using Splat; -using Xunit; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class ReactiveWindowTest - { - public class ExampleViewModel : ReactiveObject, IActivatableViewModel - { - public bool IsActive { get; private set; } - - public ViewModelActivator Activator { get; } = new ViewModelActivator(); - - public ExampleViewModel() => this.WhenActivated(disposables => - { - IsActive = true; - Disposable - .Create(() => IsActive = false) - .DisposeWith(disposables); - }); - } - - public class ExampleWindow : ReactiveWindow { } - - public ReactiveWindowTest() => - Locator - .CurrentMutable - .RegisterConstant( - new AvaloniaActivationForViewFetcher(), - typeof(IActivationForViewFetcher)); - - [Fact] - public void Data_Context_Should_Stay_In_Sync_With_Reactive_Window_View_Model() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var view = new ExampleWindow(); - var viewModel = new ExampleViewModel(); - view.Show(); - - Assert.Null(view.ViewModel); - Assert.Null(view.DataContext); - - view.DataContext = viewModel; - Assert.Equal(viewModel, view.ViewModel); - Assert.Equal(viewModel, view.DataContext); - - view.DataContext = null; - Assert.Null(view.ViewModel); - Assert.Null(view.DataContext); - - view.ViewModel = viewModel; - Assert.Equal(viewModel, view.ViewModel); - Assert.Equal(viewModel, view.DataContext); - - view.ViewModel = null; - Assert.Null(view.ViewModel); - Assert.Null(view.DataContext); - } - } - - [Fact] - public void Should_Start_With_NotNull_Activated_ViewModel() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var view = new ExampleWindow { ViewModel = new ExampleViewModel() }; - - Assert.False(view.ViewModel.IsActive); - - view.Show(); - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.True(view.ViewModel.IsActive); - - view.Close(); - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.False(view.ViewModel.IsActive); - } - } - - [Fact] - public void Should_Start_With_NotNull_Activated_DataContext() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var view = new ExampleWindow { DataContext = new ExampleViewModel() }; - - Assert.False(view.ViewModel.IsActive); - - view.Show(); - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.True(view.ViewModel.IsActive); - - view.Close(); - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(view.ViewModel); - Assert.NotNull(view.DataContext); - Assert.False(view.ViewModel.IsActive); - } - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/RoutedViewHostTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/RoutedViewHostTest.cs deleted file mode 100644 index 56c7863861..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/RoutedViewHostTest.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System; -using System.Reactive.Concurrency; -using System.Reactive.Disposables; -using Avalonia.Controls; -using Avalonia.Rendering; -using Avalonia.Platform; -using Avalonia.UnitTests; -using Avalonia; -using ReactiveUI; -using DynamicData; -using Xunit; -using Splat; -using Avalonia.Markup.Xaml; -using System.ComponentModel; -using System.Threading.Tasks; -using System.Reactive; -using Avalonia.ReactiveUI; -using Avalonia.Threading; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class RoutedViewHostTest - { - public class FirstRoutableViewModel : ReactiveObject, IRoutableViewModel - { - public string UrlPathSegment => "first"; - - public IScreen HostScreen { get; set; } - } - - public class FirstRoutableView : ReactiveUserControl { } - - public class AlternativeFirstRoutableView : ReactiveUserControl { } - - public class SecondRoutableViewModel : ReactiveObject, IRoutableViewModel - { - public string UrlPathSegment => "second"; - - public IScreen HostScreen { get; set; } - } - - public class SecondRoutableView : ReactiveUserControl { } - - public class AlternativeSecondRoutableView : ReactiveUserControl { } - - public class ScreenViewModel : ReactiveObject, IScreen - { - public RoutingState Router { get; } = new RoutingState(); - } - - public static string AlternativeViewContract => "AlternativeView"; - - public RoutedViewHostTest() - { - Locator.CurrentMutable.RegisterConstant(new AvaloniaActivationForViewFetcher(), typeof(IActivationForViewFetcher)); - Locator.CurrentMutable.Register(() => new FirstRoutableView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new SecondRoutableView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new AlternativeFirstRoutableView(), typeof(IViewFor), AlternativeViewContract); - Locator.CurrentMutable.Register(() => new AlternativeSecondRoutableView(), typeof(IViewFor), AlternativeViewContract); - } - - [Fact] - public void RoutedViewHost_Should_Stay_In_Sync_With_RoutingState() - { - var screen = new ScreenViewModel(); - var defaultContent = new TextBlock(); - var host = new RoutedViewHost - { - Router = screen.Router, - DefaultContent = defaultContent, - PageTransition = null - }; - - var root = new TestRoot - { - Child = host - }; - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(defaultContent, host.Content); - - var first = new FirstRoutableViewModel(); - screen.Router.Navigate.Execute(first).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(first, ((FirstRoutableView)host.Content).DataContext); - Assert.Equal(first, ((FirstRoutableView)host.Content).ViewModel); - - var second = new SecondRoutableViewModel(); - screen.Router.Navigate.Execute(second).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(second, ((SecondRoutableView)host.Content).DataContext); - Assert.Equal(second, ((SecondRoutableView)host.Content).ViewModel); - - screen.Router.NavigateBack.Execute(Unit.Default).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(first, ((FirstRoutableView)host.Content).DataContext); - Assert.Equal(first, ((FirstRoutableView)host.Content).ViewModel); - - screen.Router.NavigateBack.Execute(Unit.Default).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(defaultContent, host.Content); - } - - [Fact] - public void RoutedViewHost_Should_Stay_In_Sync_With_RoutingState_And_Contract() - { - var screen = new ScreenViewModel(); - var defaultContent = new TextBlock(); - var host = new RoutedViewHost - { - Router = screen.Router, - DefaultContent = defaultContent, - PageTransition = null - }; - - var root = new TestRoot - { - Child = host - }; - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(defaultContent, host.Content); - - var first = new FirstRoutableViewModel(); - screen.Router.Navigate.Execute(first).Subscribe(); - - host.ViewContract = null; - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(first, ((FirstRoutableView)host.Content).DataContext); - Assert.Equal(first, ((FirstRoutableView)host.Content).ViewModel); - - host.ViewContract = AlternativeViewContract; - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(first, ((AlternativeFirstRoutableView)host.Content).DataContext); - Assert.Equal(first, ((AlternativeFirstRoutableView)host.Content).ViewModel); - - var second = new SecondRoutableViewModel(); - screen.Router.Navigate.Execute(second).Subscribe(); - - host.ViewContract = null; - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(second, ((SecondRoutableView)host.Content).DataContext); - Assert.Equal(second, ((SecondRoutableView)host.Content).ViewModel); - - host.ViewContract = AlternativeViewContract; - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(second, ((AlternativeSecondRoutableView)host.Content).DataContext); - Assert.Equal(second, ((AlternativeSecondRoutableView)host.Content).ViewModel); - - screen.Router.NavigateBack.Execute(Unit.Default).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(first, ((AlternativeFirstRoutableView)host.Content).DataContext); - Assert.Equal(first, ((AlternativeFirstRoutableView)host.Content).ViewModel); - - screen.Router.NavigateBack.Execute(Unit.Default).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - Assert.Equal(defaultContent, host.Content); - } - - [Fact] - public void RoutedViewHost_Should_Show_Default_Content_When_Router_Is_Null() - { - var screen = new ScreenViewModel(); - var defaultContent = new TextBlock(); - var host = new RoutedViewHost - { - DefaultContent = defaultContent, - PageTransition = null, - Router = null - }; - - var root = new TestRoot - { - Child = host - }; - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(host.Content); - Assert.Equal(defaultContent, host.Content); - - host.Router = screen.Router; - - Assert.NotNull(host.Content); - Assert.Equal(defaultContent, host.Content); - - var first = new FirstRoutableViewModel(); - screen.Router.Navigate.Execute(first).Subscribe(); - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - - host.Router = null; - - Assert.NotNull(host.Content); - Assert.Equal(defaultContent, host.Content); - - host.Router = screen.Router; - - Assert.NotNull(host.Content); - Assert.IsType(host.Content); - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/TransitioningContentControlTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/TransitioningContentControlTest.cs deleted file mode 100644 index ed96c4ef6e..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/TransitioningContentControlTest.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Linq; -using Avalonia.Controls; -using Avalonia.Controls.Presenters; -using Avalonia.Controls.Templates; -using Avalonia.UnitTests; -using Avalonia.VisualTree; -using ReactiveUI; -using Splat; -using Xunit; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class TransitioningContentControlTest - { - [Fact] - public void Transitioning_Control_Template_Should_Be_Instantiated() - { - var target = new TransitioningContentControl - { - PageTransition = null, - Template = GetTemplate(), - Content = "Foo" - }; - target.ApplyTemplate(); - target.Presenter.UpdateChild(); - - var child = ((Visual)target).GetVisualChildren().Single(); - Assert.IsType(child); - child = child.GetVisualChildren().Single(); - Assert.IsType(child); - child = child.GetVisualChildren().Single(); - Assert.IsType(child); - } - - private static FuncControlTemplate GetTemplate() - { - return new FuncControlTemplate((parent, scope) => - { - return new Border - { - Background = new Media.SolidColorBrush(0xffffffff), - Child = new ContentPresenter - { - Name = "PART_ContentPresenter", - [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty], - [~ContentPresenter.ContentTemplateProperty] = parent[~ContentControl.ContentTemplateProperty], - }.RegisterInNameScope(scope) - }; - }); - } - } -} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ViewModelViewHostTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ViewModelViewHostTest.cs deleted file mode 100644 index 3d60e56c65..0000000000 --- a/tests/Avalonia.ReactiveUI.UnitTests/ViewModelViewHostTest.cs +++ /dev/null @@ -1,144 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Threading; -using Avalonia.UnitTests; -using ReactiveUI; -using Splat; -using Xunit; - -namespace Avalonia.ReactiveUI.UnitTests -{ - public class ViewModelViewHostTest - { - public class FirstViewModel { } - - public class FirstView : ReactiveUserControl { } - - public class AlternativeFirstView : ReactiveUserControl { } - - public class SecondViewModel : ReactiveObject { } - - public class SecondView : ReactiveUserControl { } - - public class AlternativeSecondView : ReactiveUserControl { } - - public static string AlternativeViewContract => "AlternativeView"; - - public ViewModelViewHostTest() - { - Locator.CurrentMutable.RegisterConstant(new AvaloniaActivationForViewFetcher(), typeof(IActivationForViewFetcher)); - Locator.CurrentMutable.Register(() => new FirstView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new SecondView(), typeof(IViewFor)); - Locator.CurrentMutable.Register(() => new AlternativeFirstView(), typeof(IViewFor), AlternativeViewContract); - Locator.CurrentMutable.Register(() => new AlternativeSecondView(), typeof(IViewFor), AlternativeViewContract); - } - - [Fact] - public void ViewModelViewHost_View_Should_Stay_In_Sync_With_ViewModel() - { - var defaultContent = new TextBlock(); - var host = new ViewModelViewHost - { - DefaultContent = defaultContent, - PageTransition = null - }; - - var root = new TestRoot - { - Child = host - }; - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(host.Content); - Assert.Equal(typeof(TextBlock), host.Content.GetType()); - Assert.Equal(defaultContent, host.Content); - - var first = new FirstViewModel(); - host.ViewModel = first; - Assert.NotNull(host.Content); - Assert.Equal(typeof(FirstView), host.Content.GetType()); - Assert.Equal(first, ((FirstView)host.Content).DataContext); - Assert.Equal(first, ((FirstView)host.Content).ViewModel); - - var second = new SecondViewModel(); - host.ViewModel = second; - Assert.NotNull(host.Content); - Assert.Equal(typeof(SecondView), host.Content.GetType()); - Assert.Equal(second, ((SecondView)host.Content).DataContext); - Assert.Equal(second, ((SecondView)host.Content).ViewModel); - - host.ViewModel = null; - Assert.NotNull(host.Content); - Assert.Equal(typeof(TextBlock), host.Content.GetType()); - Assert.Equal(defaultContent, host.Content); - - host.ViewModel = first; - Assert.NotNull(host.Content); - Assert.Equal(typeof(FirstView), host.Content.GetType()); - Assert.Equal(first, ((FirstView)host.Content).DataContext); - Assert.Equal(first, ((FirstView)host.Content).ViewModel); - } - - [Fact] - public void ViewModelViewHost_View_Should_Stay_In_Sync_With_ViewModel_And_Contract() - { - var defaultContent = new TextBlock(); - var host = new ViewModelViewHost - { - DefaultContent = defaultContent, - PageTransition = null - }; - - var root = new TestRoot - { - Child = host - }; - - Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded); - Assert.NotNull(host.Content); - Assert.Equal(typeof(TextBlock), host.Content.GetType()); - Assert.Equal(defaultContent, host.Content); - - var first = new FirstViewModel(); - host.ViewModel = first; - - host.ViewContract = null; - Assert.NotNull(host.Content); - Assert.Equal(typeof(FirstView), host.Content.GetType()); - Assert.Equal(first, ((FirstView)host.Content).DataContext); - Assert.Equal(first, ((FirstView)host.Content).ViewModel); - - host.ViewContract = AlternativeViewContract; - Assert.NotNull(host.Content); - Assert.Equal(typeof(AlternativeFirstView), host.Content.GetType()); - Assert.Equal(first, ((AlternativeFirstView)host.Content).DataContext); - Assert.Equal(first, ((AlternativeFirstView)host.Content).ViewModel); - - var second = new SecondViewModel(); - host.ViewModel = second; - - host.ViewContract = null; - Assert.NotNull(host.Content); - Assert.Equal(typeof(SecondView), host.Content.GetType()); - Assert.Equal(second, ((SecondView)host.Content).DataContext); - Assert.Equal(second, ((SecondView)host.Content).ViewModel); - - host.ViewContract = AlternativeViewContract; - Assert.NotNull(host.Content); - Assert.Equal(typeof(AlternativeSecondView), host.Content.GetType()); - Assert.Equal(second, ((AlternativeSecondView)host.Content).DataContext); - Assert.Equal(second, ((AlternativeSecondView)host.Content).ViewModel); - - host.ViewModel = null; - - host.ViewContract = null; - Assert.NotNull(host.Content); - Assert.Equal(typeof(TextBlock), host.Content.GetType()); - Assert.Equal(defaultContent, host.Content); - - host.ViewContract = AlternativeViewContract; - Assert.NotNull(host.Content); - Assert.Equal(typeof(TextBlock), host.Content.GetType()); - Assert.Equal(defaultContent, host.Content); - } - } -}