ReactiveProperty 9.6.0
dotnet add package ReactiveProperty --version 9.6.0
NuGet\Install-Package ReactiveProperty -Version 9.6.0
<PackageReference Include="ReactiveProperty" Version="9.6.0" />
paket add ReactiveProperty --version 9.6.0
#r "nuget: ReactiveProperty, 9.6.0"
// Install ReactiveProperty as a Cake Addin #addin nuget:?package=ReactiveProperty&version=9.6.0 // Install ReactiveProperty as a Cake Tool #tool nuget:?package=ReactiveProperty&version=9.6.0
ReactiveProperty
ReactiveProperty 提供在响应式扩展下的 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 | 此包包括许多扩展方法,用于从Xamarin.Android原生事件创建IObservable。 | |
ReactiveProperty.XamariniOS | 此包包括许多扩展方法,用于将ReactiveProperty和ReactiveCommand绑定到Xamarin.iOS原生控件。 |
支持
我不会关注StackOverflow和其他论坛来支持ReactiveProperty,所以请随意在GitHub问题处发表问题。我可用日语(第一语言)和英语(第二语言)。
如果发布的问题太多,那么我计划将关于功能请求、问题、问题的发布地分离。
作者信息
Yoshifumi Kawai(别名@neuecc)是位于日本东京的Cysharp,Inc的创始人/CEO/CTO。自2011年4月起被授予Microsoft MVP for Developer Technologies。他是ReactiveProperty的原始拥有者。
Takaaki Suzuki(别名@xin9le)是位于日本福井的软件开发者。自2012年7月起被授予Microsoft MVP for Developer Technologies。
Kazuki Ota(别名@okazuki)是位于日本东京的软件开发者。自2011年7月至2017年2月被授予Microsoft MVP for Windows Development。现在,他在微软日本工作。
产品 | 版本 兼容的和额外的计算目标框架版本。 |
---|---|
.NET | net5.0 已计算。 net5.0-windows 已计算。 net6.0 兼容。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 兼容。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。 |
.NET Core | netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。 |
.NET Standard | netstandard2.0 兼容。 netstandard2.1 已计算。 |
.NET Framework | net461 已计算。 net462 已计算。 net463 已计算。 net47 已计算。 net471 已计算。 net472 兼容。 net48 已计算。 net481 已计算。 |
MonoAndroid | monoandroid 已计算。 |
MonoMac | monomac 已计算。 |
MonoTouch | monotouch 已计算。 |
Tizen | tizen40 已计算。 tizen60 已计算。 |
Xamarin.iOS | xamarinios 已计算。 |
Xamarin.Mac | xamarinmac 已计算。 |
Xamarin.TVOS | xamarintvos 已计算。 |
Xamarin.WatchOS | xamarinwatchos 已计算。 |
-
.NETFramework 4.7.2
- ReactiveProperty.Core (>= 9.6.0)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Reactive (>= 6.0.1)
-
.NETStandard 2.0
- ReactiveProperty.Core (>= 9.6.0)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Reactive (>= 6.0.1)
-
net6.0
- ReactiveProperty.Core (>= 9.6.0)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Reactive (>= 6.0.1)
-
net8.0
- ReactiveProperty.Core (>= 9.6.0)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Reactive (>= 6.0.1)
NuGet包 (19)
显示依赖 ReactiveProperty 的前 5 个 NuGet 包
包 | 下载 |
---|---|
MessagePack.ReactiveProperty
适用于 C# (.NET, .NET Core, Unity, Xamarin) 的超快 MessagePack 序列化器。支持 ReactiveProperty 的扩展。 |
|
ReactiveProperty.WPF
ReactiveProperty.WPF 提供类似 EventToReactiveCommand 和 EventToReactiveProperty 的行为。 |
|
ReactiveProperty.XamarinAndroid
ReactiveProperty.XamarinAndroid 为 .NET for Android 提供许多有用的扩展方法,可用于 ReactiveProperty。 |
|
ReactiveProperty.XamariniOS
ReactiveProperty.XamariniOS 为 .NET for iOS 提供许多有用的扩展方法,可用于 ReactiveProperty。 |
|
Rx.Community.Extensions
Rx 的社区编写扩展方法 |
GitHub 仓库 (20)
显示依赖 ReactiveProperty 的前 5 个最受欢迎的 GitHub 仓库
仓库 | 星星 |
---|---|
MathewSachin/Captura
捕获屏幕、音频、光标、鼠标点击和按键
|
|
MessagePack-CSharp/MessagePack-CSharp
适用于 C# (.NET, .NET Core, Unity, Xamarin) 的超快 MessagePack 序列化器。/ msgpack.org[C#]
|
|
runceel/ReactiveProperty
ReactiveProperty 提供了在 Reactive Extensions 下的 MVVM 和异步支持特性。目标框架包括 .NET 6+、.NET Framework 4.7.2 和 .NET Standard 2.0。
|
|
dotnet/dotnet
这是.NET的虚拟单体仓库的家,它包括了构建.NET SDK所需的全部源代码
|
|
danm-de/pcsc-sharp
为.NET编写的PC/SC包装类,用C#编写
|
版本 | 下载 | 最后更新 |
---|---|---|
9.6.0 | 1,970 | 7/14/2024 |
9.5.0 | 22,870 | 2/28/2024 |
9.4.1 | 4,452 | 2/12/2024 |
9.4.0 | 800 | 2/11/2024 |
9.4.0-pre8 | 603 | 12/21/2023 |
9.4.0-pre7 | 364 | 12/21/2023 |
9.4.0-pre6 | 346 | 12/21/2023 |
9.4.0-pre5 | 355 | 12/21/2023 |
9.4.0-pre4 | 365 | 12/21/2023 |
9.3.4 | 22,861 | 10/30/2023 |
9.3.4-pre202310290551 | 417 | 10/29/2023 |
9.3.3 | 2,997 | 10/10/2023 |
9.3.2 | 6,120 | 9/25/2023 |
9.3.2-pre202309140728 | 536 | 9/14/2023 |
9.3.1 | 13,097 | 8/11/2023 |
9.3.0 | 3,084 | 7/31/2023 |
9.3.0-pre202307291429 | 655 | 7/29/2023 |
9.2.0 | 10,127 | 6/19/2023 |
9.2.0-pre202305241301 | 721 | 5/25/2023 |
9.1.2 | 25,073 | 3/12/2023 |
9.0.0 | 9,987 | 2/12/2023 |
9.0.0-pre202302040959 | 692 | 2/4/2023 |
9.0.0-pre202301080724 | 783 | 1/8/2023 |
9.0.0-pre202301050852 | 670 | 1/5/2023 |
8.2.0 | 34,721 | 11/10/2022 |
8.1.2 | 51,724 | 6/6/2022 |
8.1.2-pre202206051057 | 652 | 6/5/2022 |
8.1.1 | 4,579 | 5/27/2022 |
8.1.0 | 5,195 | 4/30/2022 |
8.1.0-pre202204290912 | 698 | 4/29/2022 |
8.1.0-pre202204290644 | 651 | 4/29/2022 |
8.0.5 | 12,023 | 3/24/2022 |
8.0.5-pre202203191529 | 700 | 3/19/2022 |
8.0.5-pre202203191312 | 657 | 3/19/2022 |
8.0.4 | 14,670 | 3/5/2022 |
8.0.4-pre202203040658 | 689 | 3/4/2022 |
8.0.3 | 38,916 | 12/5/2021 |
8.0.3-pre202112031043 | 1,364 | 12/3/2021 |
8.0.3-pre202112030833 | 1,348 | 12/3/2021 |
8.0.2 | 5,166 | 11/21/2021 |
8.0.1 | 1,511 | 11/20/2021 |
8.0.1-pre202111200140 | 1,047 | 11/20/2021 |
8.0.0 | 43,404 | 11/9/2021 |
8.0.0-pre202111090825 | 749 | 11/9/2021 |
8.0.0-pre202110240626 | 2,094 | 10/24/2021 |
8.0.0-pre202110161410 | 874 | 10/16/2021 |
8.0.0-pre202110160852 | 762 | 10/16/2021 |
8.0.0-pre202110160831 | 762 | 10/16/2021 |
8.0.0-pre202110131323 | 792 | 10/13/2021 |
8.0.0-pre202110071401 | 812 | 10/7/2021 |
8.0.0-pre202110060758 | 833 | 10/6/2021 |
8.0.0-pre202110060735 | 716 | 10/6/2021 |
8.0.0-pre202109190434 | 879 | 9/19/2021 |
8.0.0-pre202109160117 | 792 | 9/16/2021 |
8.0.0-pre202108141424 | 900 | 8/14/2021 |
8.0.0-pre202107040319 | 1,336 | 7/4/2021 |
7.12.0 | 45,442 | 8/6/2021 |
7.11.0 | 13,698 | 5/31/2021 |
7.10.0 | 11,036 | 4/29/2021 |
7.9.0 | 15,158 | 4/20/2021 |
7.8.3 | 11,828 | 3/24/2021 |
7.8.2 | 1,492 | 3/23/2021 |
7.8.1 | 4,180 | 3/11/2021 |
7.8.1-pre202103031133 | 911 | 3/3/2021 |
7.8.0 | 7,420 | 2/21/2021 |
7.8.0-pre202102210255 | 818 | 2/21/2021 |
7.8.0-pre202102201703 | 830 | 2/20/2021 |
7.7.1 | 2,142 | 2/19/2021 |
7.7.1-pre202102190925 | 833 | 2/19/2021 |
7.7.0 | 13,435 | 1/26/2021 |
7.6.1 | 4,431 | 1/15/2021 |
7.6.0 | 236,476 | 1/13/2021 |
7.5.1 | 43,929 | 10/19/2020 |
7.5.0 | 1,767 | 10/17/2020 |
7.5.0-pre202010141113 | 911 | 10/14/2020 |
7.4.1 | 21,829 | 9/23/2020 |
7.4.0 | 2,380 | 9/18/2020 |
7.3.0 | 1,902 | 9/17/2020 |
7.2.1 | 26,428 | 9/11/2020 |
7.2.0 | 52,416 | 8/4/2020 |
7.1.0 | 63,884 | 5/26/2020 |
7.1.0-pre202005251107 | 975 | 5/25/2020 |
7.0.1 | 3,913 | 5/14/2020 |
7.0.1-pre202005131606 | 974 | 5/13/2020 |
7.0.0 | 5,229 | 5/5/2020 |
7.0.0-ci20200503102823 | 988 | 5/3/2020 |
7.0.0-ci20200503100450 | 968 | 5/3/2020 |
6.2.0 | 26,169 | 1/17/2020 |
6.1.4 | 16,027 | 11/16/2019 |
6.1.3 | 21,460 | 9/26/2019 |
6.1.2 | 12,202 | 8/31/2019 |
6.0.3 | 10,436 | 7/26/2019 |
5.6.0 | 140,452 | 6/20/2019 |
5.5.1 | 54,303 | 5/22/2019 |
5.4.0 | 9,100 | 4/3/2019 |
5.4.0-pre1 | 1,440 | 4/3/2019 |
5.3.2 | 28,830 | 12/14/2018 |
5.3.1 | 2,428 | 12/13/2018 |
5.3.0 | 58,472 | 9/28/2018 |
5.2.0 | 12,548 | 8/2/2018 |
5.1.1 | 5,812 | 6/21/2018 |
5.0.0 | 5,680 | 6/3/2018 |
4.2.2 | 88,098 | 4/20/2018 |
4.2.1 | 5,201 | 3/17/2018 |
4.2.0 | 10,048 | 1/28/2018 |
4.1.1 | 3,126 | 1/20/2018 |
4.1.0 | 2,405 | 1/18/2018 |
4.0.1-pre1 | 1,830 | 1/14/2018 |
4.0.0 | 5,984 | 1/8/2018 |
4.0.0-pre5 | 1,823 | 1/6/2018 |
4.0.0-pre4 | 2,762 | 10/21/2017 |
4.0.0-pre3 | 2,375 | 6/16/2017 |
3.6.0 | 30,604 | 3/27/2017 |
3.5.1 | 26,544 | 3/3/2017 |
3.5.0 | 4,970 | 2/15/2017 |
3.4.0 | 6,053 | 11/30/2016 |
3.3.2 | 2,956 | 11/21/2016 |
3.3.1 | 3,562 | 11/15/2016 |
3.2.0 | 42,777 | 10/10/2016 |
3.1.0 | 2,404 | 10/7/2016 |
3.0.1 | 6,066 | 8/13/2016 |
3.0.0 | 9,087 | 8/12/2016 |
3.0.0-pre5 | 1,935 | 7/20/2016 |
3.0.0-pre4 | 2,021 | 7/9/2016 |
3.0.0-pre3 | 1,921 | 7/9/2016 |
3.0.0-pre2 | 1,853 | 7/9/2016 |
3.0.0-pre1 | 2,025 | 7/6/2016 |
2.9.0 | 11,512 | 7/20/2016 |
2.8.0 | 4,632 | 7/2/2016 |
2.7.4 | 2,841 | 6/24/2016 |
2.7.3.1 | 2,774 | 6/16/2016 |
2.7.3 | 3,113 | 6/6/2016 |
2.7.2 | 5,935 | 4/23/2016 |
2.7.1 | 3,906 | 4/9/2016 |
2.7.0 | 2,185 | 4/8/2016 |
2.6.2 | 2,410 | 4/2/2016 |
2.6.1 | 2,121 | 4/2/2016 |
2.6.0 | 2,451 | 3/24/2016 |
2.6.0-beta1 | 2,374 | 2/29/2016 |
2.5.0 | 6,890 | 2/7/2016 |
2.4.2 | 3,972 | 1/10/2016 |
2.4.1 | 3,134 | 12/25/2015 |
2.4.0 | 2,250 | 12/23/2015 |
2.4.0-pre3 | 1,941 | 12/23/2015 |
2.4.0-pre2 | 1,927 | 12/23/2015 |
2.4.0-pre1 | 1,947 | 12/22/2015 |
2.3.1 | 2,623 | 12/18/2015 |
2.3.0.1 | 2,945 | 12/4/2015 |
2.3.0 | 2,937 | 12/1/2015 |
2.3.0-pre4 | 2,231 | 11/27/2015 |
2.3.0-pre3 | 2,177 | 11/26/2015 |
2.3.0-pre2 | 2,150 | 11/26/2015 |
2.3.0-pre | 2,177 | 11/25/2015 |
2.2.8.1-pre | 1,976 | 11/24/2015 |
2.2.8 | 2,937 | 11/10/2015 |
2.2.7.1 | 2,716 | 10/26/2015 |
2.2.7 | 2,158 | 10/26/2015 |
2.2.6.1 | 2,596 | 10/12/2015 |
2.2.6 | 2,243 | 10/9/2015 |
2.2.5 | 3,440 | 10/1/2015 |
2.2.4 | 2,797 | 9/11/2015 |
2.2.3.1 | 3,259 | 8/28/2015 |
2.2.3 | 2,213 | 8/27/2015 |
2.2.2 | 2,877 | 7/20/2015 |
2.2.1 | 2,822 | 6/28/2015 |
2.2.0 | 3,876 | 4/24/2015 |
2.1.8.2 | 2,493 | 4/2/2015 |
2.1.8.1 | 2,460 | 3/16/2015 |
2.1.7 | 2,259 | 3/14/2015 |
2.1.6 | 2,178 | 3/14/2015 |
2.1.5 | 2,212 | 3/12/2015 |
2.1.3 | 2,194 | 3/10/2015 |
2.1.2 | 2,198 | 3/8/2015 |
2.1.1 | 2,216 | 3/7/2015 |
2.1.0 | 2,759 | 2/25/2015 |
2.0.1 | 2,712 | 2/23/2015 |
2.0.0 | 2,515 | 2/23/2015 |
2.0.0-pre8 | 2,340 | 2/23/2015 |
2.0.0-pre7 | 2,373 | 2/22/2015 |
2.0.0-pre6 | 2,327 | 2/22/2015 |
2.0.0-pre5 | 2,317 | 2/22/2015 |
2.0.0-pre4 | 2,233 | 2/22/2015 |
2.0.0-pre3 | 2,234 | 2/22/2015 |
2.0.0-pre2 | 4,189 | 2/18/2015 |
2.0.0-pre1 | 2,247 | 2/17/2015 |
1.2.1 | 2,639 | 2/21/2015 |
1.2.0 | 2,411 | 2/17/2015 |
1.1.2 | 4,704 | 2/8/2015 |
1.1.1.2 | 2,289 | 2/6/2015 |
1.1.1.1 | 3,054 | 10/19/2014 |
1.1.1 | 2,262 | 10/19/2014 |
1.1.0 | 2,488 | 10/13/2014 |
1.1.0-beta2 | 1,925 | 10/11/2014 |
1.1.0-beta1 | 1,924 | 10/11/2014 |
1.0.3.1 | 2,410 | 10/10/2014 |
1.0.3 | 2,474 | 10/9/2014 |
1.0.2.2 | 2,300 | 10/5/2014 |
1.0.2 | 2,305 | 9/27/2014 |
1.0.1.1 | 2,150 | 9/27/2014 |
1.0.1 | 2,220 | 9/27/2014 |
1.0.0.2 | 2,394 | 9/4/2014 |
1.0.0.1 | 2,251 | 9/4/2014 |
1.0.0 | 2,414 | 9/4/2014 |
0.4.5.1 | 2,718 | 6/3/2014 |
0.4.5 | 2,579 | 5/7/2014 |
0.4.5-beta3 | 1,902 | 5/6/2014 |
0.4.5-beta2 | 2,360 | 5/6/2014 |
0.4.5-beta1 | 1,904 | 5/6/2014 |
0.4.4.3 | 2,363 | 5/4/2014 |
0.4.4.2 | 2,403 | 5/3/2014 |
0.4.4.1 | 2,302 | 5/3/2014 |
0.4.4 | 2,251 | 5/3/2014 |
0.4.3.1 | 2,264 | 4/30/2014 |
0.4.2.1 | 2,767 | 4/12/2014 |
0.4.2 | 2,853 | 4/11/2014 |
0.4.2-beta5 | 2,534 | 4/11/2014 |
0.4.2-beta4 | 2,589 | 4/11/2014 |
0.4.2-beta3 | 1,985 | 4/4/2014 |
0.4.2-beta2 | 1,983 | 4/4/2014 |
0.4.2-beta1 | 1,973 | 4/1/2014 |
0.4.1 | 2,361 | 2/2/2014 |
0.4.0.1 | 2,259 | 12/31/2013 |
0.4.0-rc1 | 1,939 | 12/16/2013 |
0.3.2 | 4,271 | 11/24/2011 |
0.3.1 | 2,512 | 11/21/2011 |
0.3.0 | 2,488 | 11/20/2011 |
0.2.0 | 2,688 | 10/17/2011 |
0.1.0 | 2,801 | 10/6/2011 |