Merge pull request #416 from WCKYWCKF/reactiveUIExtension

Added features:Ursa.ReactiveUIExtension
This commit is contained in:
Dong Bin
2024-09-20 18:44:58 +08:00
committed by GitHub
7 changed files with 192 additions and 1 deletions

View File

@@ -59,6 +59,26 @@ You can now use Ursa controls in your Avalonia Application.
![Demo](./assets/demo.jpg)
## ReactiveUI
If you're familiar with and often use Avalonia.ReactiveUI for development, you can use the Irihi.Ursa.ReactiveUIExtension package. This package implements the ReactiveUI versions of UrsaWindow and UrsaView.
You just need to replace ReactiveWindow or ReactiveUserControl with ReactiveUrsaWindow or ReactiveUrsaView.
```xaml
<u:ReactiveUrsaWindow
...
xmlns:u="https://irihi.tech/ursa"
x:TypeArguments="TViewModel"
...>
...
</u:ReactiveUrsaWindow>
```
```csharp
public partial class WindowHome : ReactiveUrsaWindow<TViewModel>
{
}
```
## Support
We offer limited free community support for Semi Avalonia and Ursa. Please join our group via FeiShu(Lark)

View File

@@ -1,5 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35209.166
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa", "src\Ursa\Ursa.csproj", "{14E5B6D1-E3ED-41D7-9664-37ABE3B22558}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo", "demo\Ursa.Demo\Ursa.Demo.csproj", "{407A91FD-A88B-459B-8DCE-8C6AA98279FE}"
@@ -22,12 +25,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.PrismDialogDemo", "dem
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{9D34CC2C-9BFA-4138-BA5A-CD3744F9B589}"
ProjectSection(SolutionItems) = preProject
src\Package.props = src\Package.props
demo\Directory.Build.props = demo\Directory.Build.props
src\Package.props = src\Package.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "demo\Sandbox\Sandbox.csproj", "{1E94BAFD-867E-425F-8E12-7F416D523C94}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.ReactiveUIExtension", "src\Ursa.ReactiveUI\Ursa.ReactiveUIExtension.csproj", "{1317FA08-1C62-4E64-9568-3DF210760B48}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -74,6 +79,13 @@ Global
{1E94BAFD-867E-425F-8E12-7F416D523C94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E94BAFD-867E-425F-8E12-7F416D523C94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E94BAFD-867E-425F-8E12-7F416D523C94}.Release|Any CPU.Build.0 = Release|Any CPU
{1317FA08-1C62-4E64-9568-3DF210760B48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1317FA08-1C62-4E64-9568-3DF210760B48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1317FA08-1C62-4E64-9568-3DF210760B48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1317FA08-1C62-4E64-9568-3DF210760B48}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{407A91FD-A88B-459B-8DCE-8C6AA98279FE} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}

View File

@@ -0,0 +1,3 @@
using Avalonia.Metadata;
[assembly: XmlnsDefinition("https://irihi.tech/ursa", "Ursa.ReactiveUIExtension")]

View File

@@ -0,0 +1,63 @@
using Avalonia;
using ReactiveUI;
using Ursa.Controls;
/* These codes are ported from Avalonia.ReactiveUI.
* **/
namespace Ursa.ReactiveUIExtension;
/// <summary>
/// A ReactiveUI <see cref="UrsaView"/> that implements the <see cref="IViewFor{TViewModel}"/> interface and
/// will activate your ViewModel automatically if the view model implements <see cref="IActivatableViewModel"/>.
/// When the DataContext property changes, this class will update the ViewModel property with the new DataContext
/// value, and vice versa.
/// </summary>
/// <typeparam name="TViewModel">ViewModel type.</typeparam>
public class ReactiveUrsaView<TViewModel> : UrsaView, IViewFor<TViewModel> where TViewModel : class
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1002", Justification = "Generic avalonia property is expected here.")]
public static readonly StyledProperty<TViewModel?> ViewModelProperty = AvaloniaProperty
.Register<ReactiveUrsaView<TViewModel>, TViewModel?>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveUrsaView{TViewModel}"/> class.
/// </summary>
public ReactiveUrsaView()
{
// This WhenActivated block calls ViewModel's WhenActivated
// block if the ViewModel implements IActivatableViewModel.
this.WhenActivated(disposables => { });
}
/// <summary>
/// The ViewModel.
/// </summary>
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);
}
}
}
}

View File

@@ -0,0 +1,63 @@
using Avalonia;
using ReactiveUI;
using Ursa.Controls;
/* These codes are ported from Avalonia.ReactiveUI.
* **/
namespace Ursa.ReactiveUIExtension;
/// <summary>
/// A ReactiveUI <see cref="UrsaWindow"/> that implements the <see cref="IViewFor{TViewModel}"/> interface and will
/// activate your ViewModel automatically if the view model implements <see cref="IActivatableViewModel"/>. When
/// the DataContext property changes, this class will update the ViewModel property with the new DataContext value,
/// and vice versa.
/// </summary>
/// <typeparam name="TViewModel">ViewModel type.</typeparam>
public class ReactiveUrsaWindow<TViewModel> : UrsaWindow, IViewFor<TViewModel> where TViewModel : class
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("AvaloniaProperty", "AVP1002", Justification = "Generic avalonia property is expected here.")]
public static readonly StyledProperty<TViewModel?> ViewModelProperty = AvaloniaProperty
.Register<ReactiveUrsaWindow<TViewModel>, TViewModel?>(nameof(ViewModel));
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveUrsaWindow{TViewModel}"/> class.
/// </summary>
public ReactiveUrsaWindow()
{
// This WhenActivated block calls ViewModel's WhenActivated
// block if the ViewModel implements IActivatableViewModel.
this.WhenActivated(disposables => { });
}
/// <summary>
/// The ViewModel.
/// </summary>
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);
}
}
}
}

View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net8</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<Authors>WCKYWCKF, IRIHI Technology</Authors>
<PackageId>Irihi.Ursa.ReactiveUIExtension</PackageId>
<PackageIcon>irihi.png</PackageIcon>
<PackageProjectUrl>https://github.com/irihitech/Ursa.Avalonia</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Description>This is a Ursa expansion. This package integrates and is compatible with UrsaWindow and UrsaView with Avalonia.ReactiveUI. [Avalonia.ReactiveUI See: https://docs.avaloniaui.net/zh-Hans/docs/concepts/reactiveui/]
这个是一个Ursa拓展包。这个包整合并互相兼容了UrsaWindow和UrsaView与Avalonia.ReactiveUI的功能。【Avalonia.ReactiveUI参见https://docs.avaloniaui.net/docs/concepts/reactiveui/】</Description>
<Version>1.0.1</Version>
<Copyright></Copyright>
<RepositoryUrl>https://github.com/irihitech/Ursa.Avalonia</RepositoryUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ursa\Ursa.csproj" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB