Merge pull request #416 from WCKYWCKF/reactiveUIExtension
Added features:Ursa.ReactiveUIExtension
This commit is contained in:
20
README.md
20
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
|
||||||
|
<u:ReactiveUrsaWindow
|
||||||
|
...
|
||||||
|
xmlns:u="https://irihi.tech/ursa"
|
||||||
|
x:TypeArguments="TViewModel"
|
||||||
|
...>
|
||||||
|
...
|
||||||
|
</u:ReactiveUrsaWindow>
|
||||||
|
```
|
||||||
|
```csharp
|
||||||
|
public partial class WindowHome : ReactiveUrsaWindow<TViewModel>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
We offer limited free community support for Semi Avalonia and Ursa. Please join our group via FeiShu(Lark)
|
We offer limited free community support for Semi Avalonia and Ursa. Please join our group via FeiShu(Lark)
|
||||||
|
|||||||
14
Ursa.sln
14
Ursa.sln
@@ -1,5 +1,8 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
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}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa", "src\Ursa\Ursa.csproj", "{14E5B6D1-E3ED-41D7-9664-37ABE3B22558}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo", "demo\Ursa.Demo\Ursa.Demo.csproj", "{407A91FD-A88B-459B-8DCE-8C6AA98279FE}"
|
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
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{9D34CC2C-9BFA-4138-BA5A-CD3744F9B589}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{9D34CC2C-9BFA-4138-BA5A-CD3744F9B589}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
src\Package.props = src\Package.props
|
|
||||||
demo\Directory.Build.props = demo\Directory.Build.props
|
demo\Directory.Build.props = demo\Directory.Build.props
|
||||||
|
src\Package.props = src\Package.props
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "demo\Sandbox\Sandbox.csproj", "{1E94BAFD-867E-425F-8E12-7F416D523C94}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "demo\Sandbox\Sandbox.csproj", "{1E94BAFD-867E-425F-8E12-7F416D523C94}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.ReactiveUIExtension", "src\Ursa.ReactiveUI\Ursa.ReactiveUIExtension.csproj", "{1317FA08-1C62-4E64-9568-3DF210760B48}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{1E94BAFD-867E-425F-8E12-7F416D523C94}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{407A91FD-A88B-459B-8DCE-8C6AA98279FE} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
|
{407A91FD-A88B-459B-8DCE-8C6AA98279FE} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66}
|
||||||
|
|||||||
3
src/Ursa.ReactiveUI/AssemblyInfo.cs
Normal file
3
src/Ursa.ReactiveUI/AssemblyInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
using Avalonia.Metadata;
|
||||||
|
|
||||||
|
[assembly: XmlnsDefinition("https://irihi.tech/ursa", "Ursa.ReactiveUIExtension")]
|
||||||
63
src/Ursa.ReactiveUI/ReactiveUrsaView.cs
Normal file
63
src/Ursa.ReactiveUI/ReactiveUrsaView.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs
Normal file
63
src/Ursa.ReactiveUI/ReactiveUrsaWindow.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj
Normal file
30
src/Ursa.ReactiveUI/Ursa.ReactiveUIExtension.csproj
Normal 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>
|
||||||
BIN
src/Ursa.ReactiveUI/irihi.png
Normal file
BIN
src/Ursa.ReactiveUI/irihi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Reference in New Issue
Block a user