diff --git a/src/Directory.build.props b/src/Directory.build.props
index f286017e34..f593a6b1a0 100644
--- a/src/Directory.build.props
+++ b/src/Directory.build.props
@@ -48,11 +48,11 @@
-
+
-
+
diff --git a/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj b/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj
index 5b6fc777d6..e7d6ce6c60 100644
--- a/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj
+++ b/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj
@@ -16,11 +16,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/src/ReactiveUI.Blazor/ReactiveUI.Blazor.csproj b/src/ReactiveUI.Blazor/ReactiveUI.Blazor.csproj
index 0d41680faf..41438348e7 100644
--- a/src/ReactiveUI.Blazor/ReactiveUI.Blazor.csproj
+++ b/src/ReactiveUI.Blazor/ReactiveUI.Blazor.csproj
@@ -10,11 +10,15 @@
-
+
-
-
+
+
+
+
+
+
diff --git a/src/ReactiveUI.Maui/ReactiveShell.cs b/src/ReactiveUI.Maui/ReactiveShell.cs
new file mode 100644
index 0000000000..1c98d6a785
--- /dev/null
+++ b/src/ReactiveUI.Maui/ReactiveShell.cs
@@ -0,0 +1,54 @@
+// Copyright (c) 2022 .NET Foundation and Contributors. All rights reserved.
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using Microsoft.Maui.Controls;
+
+namespace ReactiveUI.Maui;
+
+///
+/// ReactiveShell.
+///
+/// The type of the view model.
+///
+///
+public class ReactiveShell : Shell, IViewFor
+ where TViewModel : class
+{
+ ///
+ /// The view model bindable property.
+ ///
+ public static readonly BindableProperty ViewModelProperty = BindableProperty.Create(
+ nameof(ViewModel),
+ typeof(TViewModel),
+ typeof(ReactiveShell),
+ default(TViewModel),
+ BindingMode.OneWay,
+ propertyChanged: OnViewModelChanged);
+
+ ///
+ /// Gets or sets the ViewModel to display.
+ ///
+ public TViewModel? ViewModel
+ {
+ get => (TViewModel)GetValue(ViewModelProperty);
+ set => SetValue(ViewModelProperty, value);
+ }
+
+ ///
+ object? IViewFor.ViewModel
+ {
+ get => ViewModel;
+ set => ViewModel = (TViewModel?)value;
+ }
+
+ ///
+ protected override void OnBindingContextChanged()
+ {
+ base.OnBindingContextChanged();
+ ViewModel = BindingContext as TViewModel;
+ }
+
+ private static void OnViewModelChanged(BindableObject bindableObject, object oldValue, object newValue) => bindableObject.BindingContext = newValue;
+}
diff --git a/src/ReactiveUI.Maui/ReactiveShellContent.cs b/src/ReactiveUI.Maui/ReactiveShellContent.cs
new file mode 100644
index 0000000000..35bae0095d
--- /dev/null
+++ b/src/ReactiveUI.Maui/ReactiveShellContent.cs
@@ -0,0 +1,95 @@
+// Copyright (c) 2022 .NET Foundation and Contributors. All rights reserved.
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System;
+using Microsoft.Maui.Controls;
+using Splat;
+
+namespace ReactiveUI.Maui;
+
+///
+/// ReactiveShellContent.
+///
+/// The type of the view model.
+///
+///
+public class ReactiveShellContent : ShellContent, IActivatableView
+ where TViewModel : class
+{
+ ///
+ /// The contract property.
+ ///
+ public static readonly BindableProperty ContractProperty = BindableProperty.Create(
+ nameof(Contract),
+ typeof(string),
+ typeof(ReactiveShellContent),
+ null,
+ BindingMode.Default,
+ propertyChanged: ViewModelChanged);
+
+ ///
+ /// The view model property.
+ ///
+ public static readonly BindableProperty ViewModelProperty = BindableProperty.Create(
+ nameof(ViewModel),
+ typeof(TViewModel),
+ typeof(ReactiveShellContent),
+ default(TViewModel),
+ BindingMode.Default,
+ propertyChanged: ViewModelChanged);
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ReactiveShellContent()
+ {
+ var view = Locator.Current.GetService>(Contract);
+ if (view is not null)
+ {
+ ContentTemplate = new DataTemplate(() => view);
+ }
+ }
+
+ ///
+ /// Gets or sets the view model.
+ ///
+ ///
+ /// The view model.
+ ///
+ public TViewModel? ViewModel
+ {
+ get => (TViewModel)GetValue(ViewModelProperty);
+ set => SetValue(ViewModelProperty, value);
+ }
+
+ ///
+ /// Gets or sets the contract for the view.
+ ///
+ ///
+ /// The contract.
+ ///
+ public string? Contract
+ {
+ get => (string?)GetValue(ContractProperty);
+ set => SetValue(ContractProperty, value);
+ }
+
+ private static void ViewModelChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ if (Locator.Current is null)
+ {
+ throw new NullReferenceException(nameof(Locator.Current));
+ }
+
+ if (bindable is ReactiveShellContent svm)
+ {
+ var view = Locator.Current.GetService>(svm.Contract);
+ if (view is not null)
+ {
+ svm.ContentTemplate = new DataTemplate(() => view);
+ }
+ }
+ }
+}
diff --git a/src/ReactiveUI.Tests/Platforms/winforms/API/WinformsApiApprovalTests.Winforms.DotNet6_0.verified.txt b/src/ReactiveUI.Tests/Platforms/winforms/API/WinformsApiApprovalTests.Winforms.DotNet6_0.verified.txt
index c4fc4fb7f8..490296ccf6 100644
--- a/src/ReactiveUI.Tests/Platforms/winforms/API/WinformsApiApprovalTests.Winforms.DotNet6_0.verified.txt
+++ b/src/ReactiveUI.Tests/Platforms/winforms/API/WinformsApiApprovalTests.Winforms.DotNet6_0.verified.txt
@@ -1,4 +1,6 @@
-[assembly: System.Runtime.Versioning.TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName=".NET Framework 4.6.2")]
+[assembly: System.Runtime.Versioning.SupportedOSPlatform("Windows10.0.17763.0")]
+[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName=".NET 6.0")]
+[assembly: System.Runtime.Versioning.TargetPlatform("Windows10.0.17763.0")]
namespace ReactiveUI.Winforms
{
public class ActivationForViewFetcher : ReactiveUI.IActivationForViewFetcher, Splat.IEnableLogger
@@ -106,4 +108,12 @@ namespace ReactiveUI.Winforms
public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = false) { }
public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false) { }
}
+}
+namespace System.Reactive.Concurrency
+{
+ public class ControlScheduler : System.Reactive.Concurrency.LocalScheduler, System.Reactive.Concurrency.ISchedulerPeriodic { }
+}
+namespace System.Reactive.Linq
+{
+ public static class ControlObservable { }
}
\ No newline at end of file
diff --git a/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj b/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj
index c882b0aa48..426d7879ce 100644
--- a/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj
+++ b/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj
@@ -1,8 +1,8 @@
-
+
net462;net6.0
- net472;net6.0-windows
+ net472;net6.0-windows10.0.17763.0
$(NoWarn);CS1591