ReactiveProperty.WPF 9.6.0
dotnet add package ReactiveProperty.WPF --version 9.6.0
NuGet\Install-Package ReactiveProperty.WPF -Version 9.6.0
<PackageReference Include="ReactiveProperty.WPF" Version="9.6.0" />
paket add ReactiveProperty.WPF --version 9.6.0
#r "nuget: ReactiveProperty.WPF, 9.6.0"
// Install ReactiveProperty.WPF as a Cake Addin #addin nuget:?package=ReactiveProperty.WPF&version=9.6.0 // Install ReactiveProperty.WPF as a Cake Tool #tool nuget:?package=ReactiveProperty.WPF&version=9.6.0
ReactiveProperty
ReactiveProperty 为 Reactive Extensions 提供了 MVVM 和异步支持特性。目标框架是 .NET 6.0+,.NET Framework 4.7.2 和 .NET Standard 2.0。
注意
如果您正在开发新应用程序,考虑使用 R3 而不是 ReactiveProperty。R3 是由原始作者重新设计的,与当前的 .NET 生态系统保持一致,并提供了与 ReactiveProperty 相似的大部分特性。
概念
ReactiveProperty 是一个非常强大且简单的库。
此示例应用程序的 ViewModel 代码如下:
public class MainPageViewModel
{
public ReactivePropertySlim<string> Input { get; }
public ReadOnlyReactivePropertySlim<string> Output { get; }
public MainPageViewModel()
{
Input = new ReactivePropertySlim<string>("");
Output = Input
.Delay(TimeSpan.FromSeconds(1))
.Select(x => x.ToUpper())
.ObserveOnDispatcher()
.ToReadOnlyReactivePropertySlim();
}
}
确实很简单易懂(我认为!)因为没有基类和接口。只是在输入属性和输出属性之间有声明性代码。
所有步骤均在 ReactiveProperty 文档的“入门”部分 中进行了说明。
ReactiveProperty 的概念很简单,它是一个核心类,名称为 ReactiveProperty[Slim]
,它只是一个包含值的包装类,并实现了 IObservable<T>
和 INotifyPropertyChanged
,IObservable<T>
用于将属性的变更事件连接到 Rx LINQ 方法的变更,INotifyPropertyChanged
用于数据绑定系统,如 WPF、WinUI 和 MAUI。
ReactiveProperty 的重要概念之一是“函数式编程”。使用 ReactiveProperty 的 ViewModel 代码非常简单。
ViewModel 的常用实现
public class AViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
// Update a command status
DoSomethingCommand.RaiseCanExecuteChanged();
}
}
private string _memo;
public string Memo
{
get => _memo;
set
{
_memo = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Memo)));
// Update a command status
DoSomethingCommand.RaiseCanExecuteChanged();
}
}
// DelegateCommand is plane ICommand implementation.
public DelegateCommand DoSomethingCommand { get; }
public AViewModel()
{
DoSomethingCommand = new DelegateCommand(
() => { ... },
() => !string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Memo)
);
}
}
绑定代码
<TextBlock Text="{Binding Name}">
<TextBlock Text="{Binding Memo}">
使用 ReactiveProperty 的 ViewModel 实现
public class AViewModel
{
public ValidatableReactiveProperty<string> Name { get; }
public ValidatableReactiveProperty<string> Memo { get; }
public ReactiveCommandSlim DoSomethingCommand { get; }
public AViewModel()
{
Name = new ValidatableReactiveProperty<string>("",
x => string.IsNullOrEmpty(x) ? "Invalid value" : null);
Memo = new ValidatableReactiveProperty<string>("",
x => string.IsNullOrEmpty(x) ? "Invalid value" : null);
DoSomethingCommand = new[]
{
Name.ObserveHasErrors,
Memo.ObserveHasErrors,
}
.CombineLatestValuesAreAllFalse()
.ToReactiveCommand()
.WithSubscribe(() => { ... });
}
}
绑定代码
<TextBlock Text="{Binding Name.Value}">
<TextBlock Text="{Binding Memo.Value}">
非常简单。
ReactiveProperty 不提供由 ViewModel 提供的基类,这意味着 ReactiveProperty 可以与其他 MVVM 库(如 Prism、Microsoft.Toolkit.Mvvm 等)一起使用。
文档
NuGet 包
包 ID | 版本和下载 | 描述 |
---|---|---|
ReactiveProperty | 该包包括所有核心功能。 | |
ReactiveProperty.Core | 该包包含最小类,例如 ReactivePropertySlim<T> 和 ReadOnlyReactivePropertySlim<T> 。而且这没有任何依赖,甚至没有 System.Reactive。如果您不需要 Rx 功能,那么它非常适合。 |
|
ReactiveProperty.WPF | 该包包含适用于 WPF 的 EventToReactiveProperty 和 EventToReactiveCommand。这是针对 .NET 6 或更高版本和 .NET Framework 4.7.2 或更高版本。 | |
ReactiveProperty.Blazor | 该包包含对 Blazor EditForm 组件的验证支持,具有 ReactiveProperty 验证功能。这是针对 .NET 6.0 或更高版本。 |
以下包处于维护阶段。
包 ID | 版本和下载 | 描述 |
---|---|---|
ReactiveProperty.UWP | 该包包含适用于 UWP 的 EventToReactiveProperty 和 EventToReactiveCommand。 | |
ReactiveProperty.XamarinAndroid | 该包包含许多扩展方法,可以将事件创建为 IObservable,用于 Xamarin.Android 本机。 | |
ReactiveProperty.XamariniOS | 该包包含许多扩展方法,可以将 ReactiveProperty 和 ReactiveCommand 绑定为 Xamarin.iOS 本机控件。 |
支持
我不会关注 StackOverflow 和其他论坛以支持 ReactiveProperty,所以请在 GitHub 问题中自由发表问题。我可以说日语(第一语言)和英语(第二语言)。
如果发出的问题太多,那么我计划将关于功能请求、问题、问题的发表地方分开。
作者信息
Yoshifumi Kawai(又名 @neuecc)是日本东京的 Cysharp,Inc 的创始人/CEO/CTO。自 2011 年 4 月以来获得微软 MVP 开发技术奖。他是 ReactiveProperty 的原始拥有者。
Takaaki Suzuki(又名 @xin9le)是日本福井的软件开发人员。自 2012 年 7 月以来获得微软 MVP 开发技术奖。
Kazuki Ota(又名 @okazuki)是日本东京的软件开发人员。自 2011 年 7 月至 2017 年 2 月获得微软 MVP Windows 开发奖。现在在微软日本工作。
产品 | 版本 兼容的和额外的计算目标框架版本。 |
---|---|
.NET | net6.0-windows7.0 是兼容的。 net7.0-windows 已被计算。 net8.0-windows 已被计算。 net8.0-windows7.0 是兼容的。 |
.NET Framework | net472 是兼容的。 net48 已被计算。 net481 已被计算。 |
-
.NETFramework 4.7.2
- Microsoft.Xaml.Behaviors.Wpf (>= 1.1.122)
- ReactiveProperty (≥9.6.0)
-
net6.0-windows7.0
- Microsoft.Xaml.Behaviors.Wpf (>= 1.1.122)
- ReactiveProperty (≥9.6.0)
-
net8.0-windows7.0
- Microsoft.Xaml.Behaviors.Wpf (>= 1.1.122)
- ReactiveProperty (≥9.6.0)
NuGet 包 (1)
显示依赖于ReactiveProperty.WPF的前1个NuGet软件包
软件包 | 下载 |
---|---|
Codeer.LowCode.Blazor.Designer
这是一个为Blazor应用程序添加低码功能的库。 |
GitHub仓库
此软件包没有被任何流行的GitHub仓库使用。
版本 | 下载 | 最后更新 |
---|---|---|
9.6.0 | 534 | 7/14/2024 |
9.5.0 | 5,348 | 2/28/2024 |
9.4.1 | 684 | 2/12/2024 |
9.4.0 | 132 | 2/11/2024 |
9.4.0-pre8 | 160 | 12/21/2023 |
9.4.0-pre7 | 62 | 12/21/2023 |
9.4.0-pre6 | 61 | 12/21/2023 |
9.4.0-pre5 | 60 | 12/21/2023 |
9.4.0-pre4 | 68 | 12/21/2023 |
9.3.4 | 3,598 | 10/30/2023 |
9.3.4-pre202310290551 | 92 | 10/29/2023 |
9.3.3 | 583 | 10/10/2023 |
9.3.2 | 654 | 9/25/2023 |
9.3.2-pre202309140728 | 93 | 9/14/2023 |
9.3.1 | 2,999 | 8/11/2023 |
9.3.0 | 566 | 7/31/2023 |
9.3.0-pre202307291429 | 116 | 7/29/2023 |
9.2.0 | 1,387 | 6/19/2023 |
9.2.0-pre202305241301 | 115 | 5/25/2023 |
9.1.2 | 8,078 | 3/12/2023 |
9.0.0 | 3,354 | 2/12/2023 |
9.0.0-pre202302040959 | 127 | 2/4/2023 |
9.0.0-pre202301080724 | 153 | 1/8/2023 |
9.0.0-pre202301050852 | 142 | 1/5/2023 |
8.2.0 | 5,985 | 11/10/2022 |
8.1.2 | 18,669 | 6/6/2022 |
8.1.2-pre202206051057 | 153 | 6/5/2022 |
8.1.1 | 907 | 5/27/2022 |
8.1.0 | 1,421 | 4/30/2022 |
8.1.0-pre202204290912 | 161 | 4/29/2022 |
8.1.0-pre202204290644 | 131 | 4/29/2022 |
8.0.5 | 1,632 | 3/24/2022 |
8.0.5-pre202203191529 | 154 | 3/19/2022 |
8.0.5-pre202203191312 | 147 | 3/19/2022 |
8.0.4 | 1,556 | 3/5/2022 |
8.0.4-pre202203040658 | 159 | 3/4/2022 |
8.0.3 | 14,279 | 12/5/2021 |
8.0.3-pre202112031043 | 845 | 12/3/2021 |
8.0.3-pre202112030833 | 784 | 12/3/2021 |
8.0.2 | 1,579 | 11/21/2021 |
8.0.1 | 529 | 11/20/2021 |
8.0.1-pre202111200140 | 548 | 11/20/2021 |
8.0.0 | 698 | 11/9/2021 |
8.0.0-pre202111090825 | 173 | 11/9/2021 |
8.0.0-pre202110240626 | 215 | 10/24/2021 |
8.0.0-pre202110161410 | 289 | 10/16/2021 |
8.0.0-pre202110160852 | 216 | 10/16/2021 |
8.0.0-pre202110160831 | 221 | 10/16/2021 |
8.0.0-pre202110131323 | 226 | 10/13/2021 |
8.0.0-pre202110071401 | 248 | 10/7/2021 |
8.0.0-pre202110060758 | 250 | 10/6/2021 |
8.0.0-pre202109190434 | 312 | 9/19/2021 |
8.0.0-pre202109160117 | 245 | 9/16/2021 |
8.0.0-pre202108141424 | 276 | 8/14/2021 |
8.0.0-pre202107040319 | 329 | 7/4/2021 |
7.12.0 | 26,177 | 8/6/2021 |
7.11.0 | 4,461 | 5/31/2021 |
7.10.0 | 4,304 | 4/29/2021 |
7.9.0 | 10,328 | 4/20/2021 |
7.8.3 | 1,431 | 3/24/2021 |
7.8.2 | 377 | 3/23/2021 |
7.8.1 | 711 | 3/11/2021 |
7.8.1-pre202103031133 | 242 | 3/3/2021 |
7.8.0 | 1,391 | 2/21/2021 |
7.8.0-pre202102210255 | 223 | 2/21/2021 |
7.8.0-pre202102201703 | 238 | 2/20/2021 |
7.7.1 | 401 | 2/19/2021 |
7.7.1-pre202102190925 | 188 | 2/19/2021 |
7.7.0 | 8,491 | 1/26/2021 |
7.6.1 | 651 | 1/15/2021 |
7.6.0 | 510 | 1/13/2021 |
7.5.1 | 2,654 | 10/19/2020 |
7.5.0 | 473 | 10/17/2020 |
7.5.0-pre202010141113 | 281 | 10/14/2020 |
7.4.1 | 11,366 | 9/23/2020 |
7.4.0 | 551 | 9/18/2020 |
7.3.0 | 511 | 9/17/2020 |
7.2.1 | 5,743 | 9/11/2020 |
7.2.0 | 1,069 | 8/4/2020 |
7.1.0 | 2,180 | 5/26/2020 |
7.1.0-pre202005251107 | 356 | 5/25/2020 |
7.0.1 | 637 | 5/14/2020 |
7.0.1-pre202005131606 | 303 | 5/13/2020 |
7.0.0 | 881 | 5/5/2020 |
7.0.0-ci20200503102823 | 363 | 5/3/2020 |
7.0.0-ci20200503100450 | 350 | 5/3/2020 |