From 4c50d282838bc5ff223095a43aea21317c2b6a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9B=E5=B0=98=E7=A9=BA=E5=BF=A7?= Date: Fri, 20 Sep 2024 15:36:38 +0800 Subject: [PATCH 1/3] Added features:Ursa.ReactiveUIExtension --- src/Ursa.ReactiveUI/AssemblyInfo.cs | 3 + src/Ursa.ReactiveUI/ReactiveUrsaView.cs | 63 ++++++++++++++++++ src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs | 63 ++++++++++++++++++ .../Ursa.ReactiveUIExtension.csproj | 27 ++++++++ src/Ursa.ReactiveUI/irihi.png | Bin 0 -> 1508 bytes 5 files changed, 156 insertions(+) create mode 100644 src/Ursa.ReactiveUI/AssemblyInfo.cs create mode 100644 src/Ursa.ReactiveUI/ReactiveUrsaView.cs create mode 100644 src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs create mode 100644 src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj create mode 100644 src/Ursa.ReactiveUI/irihi.png diff --git a/src/Ursa.ReactiveUI/AssemblyInfo.cs b/src/Ursa.ReactiveUI/AssemblyInfo.cs new file mode 100644 index 0000000..5d28eeb --- /dev/null +++ b/src/Ursa.ReactiveUI/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using Avalonia.Metadata; + +[assembly: XmlnsDefinition("https://irihi.tech/ursa", "Ursa.ReactiveUIExtension")] \ No newline at end of file diff --git a/src/Ursa.ReactiveUI/ReactiveUrsaView.cs b/src/Ursa.ReactiveUI/ReactiveUrsaView.cs new file mode 100644 index 0000000..b725b23 --- /dev/null +++ b/src/Ursa.ReactiveUI/ReactiveUrsaView.cs @@ -0,0 +1,63 @@ +using Avalonia; +using ReactiveUI; +using Ursa.Controls; + +/* These codes are ported from Avalonia.ReactiveUI. + * **/ + +namespace Ursa.ReactiveUIExtension; +/// +/// 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 ReactiveUrsaView : UrsaView, 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 ReactiveUrsaView() + { + // 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); + } + } + } +} \ No newline at end of file diff --git a/src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs b/src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs new file mode 100644 index 0000000..36d58a5 --- /dev/null +++ b/src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs @@ -0,0 +1,63 @@ +using Avalonia; +using ReactiveUI; +using Ursa.Controls; + +/* These codes are ported from Avalonia.ReactiveUI. + * **/ + +namespace Ursa.ReactiveUIExtension; +/// +/// 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 ReactiveUrsaWindow : UrsaWindow, 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 ReactiveUrsaWindow() + { + // 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); + } + } + } +} \ No newline at end of file diff --git a/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj b/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj new file mode 100644 index 0000000..80bc0ff --- /dev/null +++ b/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj @@ -0,0 +1,27 @@ + + + + netstandard2.0;net8 + enable + latest + WCKFWCKY + Irihi.Ursa.ReactiveUIExtension + irihi.png + https://github.com/irihitech/Ursa.Avalonia + MIT + enable + True + This is a Ursa expansion. This package integrates and is compatible with UrsaWindow and UrsaView with Avalonia.ReactiveUI. [Avalonia.ReactiveU See: https://docs.avaloniaui.net/zh-Hans/docs/concepts/reactiveui/] + +这个是一个Ursa拓展包。这个包整合并互相兼容了UrsaWindow和UrsaView与Avalonia.ReactiveUI的功能。【Avalonia.ReactiveU参见:https://docs.avaloniaui.net/docs/concepts/reactiveui/】 + 1.0.1 + WCKFWCKY + https://github.com/irihitech/Ursa.Avalonia + + + + + + + + diff --git a/src/Ursa.ReactiveUI/irihi.png b/src/Ursa.ReactiveUI/irihi.png new file mode 100644 index 0000000000000000000000000000000000000000..01c68d918e31705d8d659505b74b764ec3b72ac4 GIT binary patch literal 1508 zcmeAS@N?(olHy`uVBq!ia0y~yV9Wqv4mO}j)zieQK#H@#BeIx*f$uN~Gak=hkpdKy zEOCt}3C>R|DNig)WhgH%*UQYyE>2D?NY%?PN}v7CMv8%fwb0YWF{EP7+iM4NpE&R^ z9K7tvnbRUYTPcL2gyCDUqS>2OEGHP*c;$?Z|1+HUxqmMMgS~J@gGM7;htMcRd=OY| z7q7VWv1 Date: Fri, 20 Sep 2024 16:54:57 +0800 Subject: [PATCH 2/3] 1. Fixed the bug of package description. 2. Change the package reference to a project reference. 3. Change the author item to a more appropriate description. --- Ursa.sln | 14 +++++++++++++- .../Ursa.ReactiveUIExtension.csproj | 13 ++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Ursa.sln b/Ursa.sln index 8e0c259..ab83bf9 100644 --- a/Ursa.sln +++ b/Ursa.sln @@ -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} diff --git a/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj b/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj index 80bc0ff..a530383 100644 --- a/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj +++ b/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj @@ -4,24 +4,27 @@ netstandard2.0;net8 enable latest - WCKFWCKY + WCKYWCKF, IRIHI Technology Irihi.Ursa.ReactiveUIExtension irihi.png https://github.com/irihitech/Ursa.Avalonia MIT enable True - This is a Ursa expansion. This package integrates and is compatible with UrsaWindow and UrsaView with Avalonia.ReactiveUI. [Avalonia.ReactiveU See: https://docs.avaloniaui.net/zh-Hans/docs/concepts/reactiveui/] + 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.ReactiveU参见:https://docs.avaloniaui.net/docs/concepts/reactiveui/】 +这个是一个Ursa拓展包。这个包整合并互相兼容了UrsaWindow和UrsaView与Avalonia.ReactiveUI的功能。【Avalonia.ReactiveUI参见:https://docs.avaloniaui.net/docs/concepts/reactiveui/】 1.0.1 - WCKFWCKY + https://github.com/irihitech/Ursa.Avalonia - + + + + From 04ba2243a0990ef1685577ec43823d91e78ba782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9B=E5=B0=98=E7=A9=BA=E5=BF=A7?= Date: Fri, 20 Sep 2024 17:23:53 +0800 Subject: [PATCH 3/3] Add a description of Ursa.ReactiveUIExtension to RAEADME. --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 54d11b1..fb83a2d 100644 --- a/README.md +++ b/README.md @@ -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 + +... + +``` +```csharp +public partial class WindowHome : ReactiveUrsaWindow +{ + +} +``` + ## Support We offer limited free community support for Semi Avalonia and Ursa. Please join our group via FeiShu(Lark)