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.

+## 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)
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/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..a530383
--- /dev/null
+++ b/src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj
@@ -0,0 +1,30 @@
+
+
+
+ netstandard2.0;net8
+ enable
+ latest
+ 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.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/】
+ 1.0.1
+
+ 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 0000000..01c68d9
Binary files /dev/null and b/src/Ursa.ReactiveUI/irihi.png differ