Skip to content

Commit

Permalink
Add Feature to MAUI (#3475)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisPulman committed Feb 18, 2023
1 parent 544e204 commit 17ab166
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/Directory.build.props
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@
<PackageReference Include="xunit.runner.console" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageReference Include="Xunit.StaFact" Version="1.1.11" />
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="FluentAssertions" Version="6.10.0" />
<PackageReference Include="Microsoft.Reactive.Testing" Version="5.0.0" />
<PackageReference Include="PublicApiGenerator" Version="10.3.0" />
<PackageReference Include="coverlet.msbuild" Version="3.2.0" PrivateAssets="All" />
<PackageReference Include="Verify.Xunit" Version="19.8.1" />
<PackageReference Include="Verify.Xunit" Version="19.9.3" />
</ItemGroup>

<ItemGroup Condition="'$(IsTestProject)' != 'true'">
Expand Down
10 changes: 5 additions & 5 deletions src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.9.0.1" />
<PackageReference Include="Xamarin.AndroidX.Preference" Version="1.2.0.3" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.Core.UI" Version="1.0.0.16" />
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.7.0.1" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.5.1.1" />
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.9.0.2" />
<PackageReference Include="Xamarin.AndroidX.Preference" Version="1.2.0.4" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.Core.UI" Version="1.0.0.17" />
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.7.0.2" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.5.1.2" />
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
Expand Down
10 changes: 7 additions & 3 deletions src/ReactiveUI.Blazor/ReactiveUI.Blazor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.17" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.32" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6')) or $(TargetFramework.StartsWith('net7')) ">
<PackageReference Include="Microsoft.AspNetCore.Components" Version="6.0.10" />
<ItemGroup Condition=" $(TargetFramework.StartsWith('net6')) ">
<PackageReference Include="Microsoft.AspNetCore.Components" Version="6.0.14" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net7')) ">
<PackageReference Include="Microsoft.AspNetCore.Components" Version="7.0.3" />
</ItemGroup>

<ItemGroup>
Expand Down
54 changes: 54 additions & 0 deletions src/ReactiveUI.Maui/ReactiveShell.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// ReactiveShell.
/// </summary>
/// <typeparam name="TViewModel">The type of the view model.</typeparam>
/// <seealso cref="Microsoft.Maui.Controls.Shell" />
/// <seealso cref="ReactiveUI.IViewFor&lt;TViewModel&gt;" />
public class ReactiveShell<TViewModel> : Shell, IViewFor<TViewModel>
where TViewModel : class
{
/// <summary>
/// The view model bindable property.
/// </summary>
public static readonly BindableProperty ViewModelProperty = BindableProperty.Create(
nameof(ViewModel),
typeof(TViewModel),
typeof(ReactiveShell<TViewModel>),
default(TViewModel),
BindingMode.OneWay,
propertyChanged: OnViewModelChanged);

/// <summary>
/// Gets or sets the ViewModel to display.
/// </summary>
public TViewModel? ViewModel
{
get => (TViewModel)GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}

/// <inheritdoc/>
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (TViewModel?)value;
}

/// <inheritdoc/>
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
ViewModel = BindingContext as TViewModel;
}

private static void OnViewModelChanged(BindableObject bindableObject, object oldValue, object newValue) => bindableObject.BindingContext = newValue;
}
95 changes: 95 additions & 0 deletions src/ReactiveUI.Maui/ReactiveShellContent.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// ReactiveShellContent.
/// </summary>
/// <typeparam name="TViewModel">The type of the view model.</typeparam>
/// <seealso cref="Microsoft.Maui.Controls.ShellContent" />
/// <seealso cref="ReactiveUI.IActivatableView" />
public class ReactiveShellContent<TViewModel> : ShellContent, IActivatableView
where TViewModel : class
{
/// <summary>
/// The contract property.
/// </summary>
public static readonly BindableProperty ContractProperty = BindableProperty.Create(
nameof(Contract),
typeof(string),
typeof(ReactiveShellContent<TViewModel>),
null,
BindingMode.Default,
propertyChanged: ViewModelChanged);

/// <summary>
/// The view model property.
/// </summary>
public static readonly BindableProperty ViewModelProperty = BindableProperty.Create(
nameof(ViewModel),
typeof(TViewModel),
typeof(ReactiveShellContent<TViewModel>),
default(TViewModel),
BindingMode.Default,
propertyChanged: ViewModelChanged);

/// <summary>
/// Initializes a new instance of the <see cref="ReactiveShellContent{TViewModel}" /> class.
/// </summary>
public ReactiveShellContent()
{
var view = Locator.Current.GetService<IViewFor<TViewModel>>(Contract);
if (view is not null)
{
ContentTemplate = new DataTemplate(() => view);
}
}

/// <summary>
/// Gets or sets the view model.
/// </summary>
/// <value>
/// The view model.
/// </value>
public TViewModel? ViewModel
{
get => (TViewModel)GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, value);
}

/// <summary>
/// Gets or sets the contract for the view.
/// </summary>
/// <value>
/// The contract.
/// </value>
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<TViewModel> svm)
{
var view = Locator.Current.GetService<IViewFor<TViewModel>>(svm.Contract);
if (view is not null)
{
svm.ContentTemplate = new DataTemplate(() => view);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -106,4 +108,12 @@ namespace ReactiveUI.Winforms
public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = false) { }
public System.IObservable<ReactiveUI.IObservedChange<object, object?>> 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 { }
}
4 changes: 2 additions & 2 deletions src/ReactiveUI.Tests/ReactiveUI.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="MSBuild.Sdk.Extras">
<Project Sdk="MSBuild.Sdk.Extras">

<PropertyGroup>
<TargetFrameworks>net462;net6.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net472;net6.0-windows</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net472;net6.0-windows10.0.17763.0</TargetFrameworks>
<NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup>

Expand Down

0 comments on commit 17ab166

Please sign in to comment.