Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Japanese](https://qiita.com/okazuki/items/7572f46848d0e93516b1)
[日本語ドキュメント](docs/docs-ja/README.md)

# ReactiveProperty

Expand Down Expand Up @@ -43,7 +43,7 @@ public class MainPageViewModel

It is really simple and understandable (I think!). Because there are NOT any base classes and interfaces. Just has declarative code between Input property and Output property.

All steps are written in the "Getting Started" section in the [ReactiveProperty documentation](https://github.com/runceel/ReactiveProperty/tree/main/docs).
All steps are written in the "Getting Started" section in the [ReactiveProperty documentation](docs/docs/README.md).

The concept of ReactiveProperty is simple that is a core class what name is `ReactiveProperty[Slim]`, it is just a wrap class what has a value, and implements `IObservable<T>` and `INotifyPropertyChanged`, `IObservable<T>` is for connect change event of the property value to Rx LINQ method chane, `INotifyPropertyChanged` is for data binding system such as WPF, WinUI and MAUI.

Expand Down Expand Up @@ -142,7 +142,8 @@ ReactiveProperty doesn't provide base class by ViewModel, which means that React

## Documentation

[ReactiveProperty documentation](https://github.com/runceel/ReactiveProperty/tree/main/docs)
- [ReactiveProperty documentation](docs/docs/README.md)
- [日本語ドキュメント](docs/docs-ja/README.md)

## NuGet packages

Expand Down
126 changes: 126 additions & 0 deletions docs/docs-ja/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# ReactiveProperty とは

ReactiveProperty は Reactive Extensions 向けに MVVM と非同期処理を支援する機能を提供します。ターゲット フレームワークは .NET Standard 2.0 です。

![概要](../docs/images/rpsummary.png)

ReactiveProperty のコンセプトは <b>楽しいプログラミング</b> です。
ReactiveProperty を使うと MVVM アプリケーションを記述できます。とても楽しいですよ!

![UWP](../docs/images/launch-uwp-app.gif)

次のコードは、ReactiveProperty と通常のオブジェクト プロパティの間の双方向バインディングを示しています。

```csharp
class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private string _name;
public string Name
{
get => _name;
set
{
_name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
}
class ViewModel
{
private readonly Model _model = new Model();
public ReactiveProperty<string> Name { get; }
public ViewModel()
{
// ReactiveProperty と Model#Name プロパティの双方向同期。
Name = _model.ToReactivePropertyAsSynchronized(x => x.Name);
}
}
```

ReactiveProperty は `IObservable<T>` を通じて実装されています。そうです!LINQ を使えます。

```csharp
var name = new ReactiveProperty<string>();
name.Where(x => x.StartsWith("_")) // フィルター
.Select(x => x.ToUpper()) // 変換
.Subscribe(x => { ... 何らかの処理 ... });
```

ReactiveProperty は `IObservable<T>` から作成されます。

```csharp
class ViewModel
{
public ReactiveProperty<string> Input { get; }
public ReactiveProperty<string> Output { get; }

public ViewModel()
{
Input = new ReactiveProperty("");
Output = Input
.Delay(TimeSpan.FromSeconds(1)) // Rx メソッドを使用。
.Select(x => x.ToUpper()) // LINQ メソッドを使用。
.ToReactiveProperty(); // ReactiveProperty に変換
}
}
```

このメソッド チェーンはとてもクールです。

`ICommand` と `IObservable<T>` インターフェイスを実装する `ReactiveCommand` クラスも提供しています。`ReactiveCommand` は `IObservable<bool>` から作成できます。
次のサンプルでは、`Input` プロパティが空でないときに実行できる `ReactiveCommand` を作成します。

```csharp
class ViewModel
{
public ReactiveProperty<string> Input { get; }
public ReactiveProperty<string> Output { get; }

public ReactiveCommand ResetCommand { get; }

public ViewModel()
{
Input = new ReactiveProperty("");
// 上のサンプルと同じ
Output = Input
.Delay(TimeSpan.FromSeconds(1)) // Rx メソッドを使用。
.Select(x => x.ToUpper()) // LINQ メソッドを使用。
.ToReactiveProperty(); // ReactiveProperty に変換

ResetCommand = Input.Select(x => !string.IsNullOrWhiteSpace(x)) // ReactiveProperty<string> を IObservable<bool> に変換
.ToReactiveCommand() // IObservable<bool> から ReactiveCommand を作成できます。true 値が発行されると、コマンドを実行できます。
.WithSubscribe(() => Input.Value = ""); // ResetCommand.Subscribe(() => ...) のショートカットです。
}
}
```

クールです!本当に宣言的で分かりやすいです。

## 始めましょう!

ReactiveProperty は次のリンクから使い始めることができます。

- [Windows Presentation Foundation](getting-started/wpf.md)
- [Universal Windows Platform](getting-started/uwp.md)
- [Xamarin.Forms](getting-started/xf.md)
- [Uno Platform](getting-started/uno-platform.md)

コア機能については、次のリンクで学べます。

- [ReactiveProperty](features/ReactiveProperty.md)
- [コマンド](features/Commanding.md)
- [コレクション](features/Collections.md)


## NuGet パッケージ

|パッケージ ID|バージョンとダウンロード数|説明|
|----|----|----|
|ReactiveProperty|![](https://img.shields.io/nuget/v/ReactiveProperty.svg)![](https://img.shields.io/nuget/dt/ReactiveProperty.svg)|すべてのコア機能が含まれ、ターゲット プラットフォームは .NET Standard 2.0 です。ほぼすべての状況に適しています。|
|ReactiveProperty.Core|![](https://img.shields.io/nuget/v/ReactiveProperty.Core.svg)![](https://img.shields.io/nuget/dt/ReactiveProperty.Core.svg)|`ReactivePropertySlim<T>` や `ReadOnlyReactivePropertySlim<T>` など、最小限のクラスが含まれます。System.Reactive にも依存しません。Rx 機能が不要な場合に適しています。|
|ReactiveProperty.WPF|![](https://img.shields.io/nuget/v/ReactiveProperty.WPF.svg)![](https://img.shields.io/nuget/dt/ReactiveProperty.WPF.svg)|WPF 向けの EventToReactiveProperty と EventToReactiveCommand が含まれます。.NET Core 3.0 以降および .NET Framework 4.7.2 以降向けです。|
|ReactiveProperty.UWP|![](https://img.shields.io/nuget/v/ReactiveProperty.UWP.svg)![](https://img.shields.io/nuget/dt/ReactiveProperty.UWP.svg)|UWP 向けの EventToReactiveProperty と EventToReactiveCommand が含まれます。|
|ReactiveProperty.XamarinAndroid|![](https://img.shields.io/nuget/v/ReactiveProperty.XamarinAndroid.svg)![](https://img.shields.io/nuget/dt/ReactiveProperty.XamarinAndroid.svg)|Xamarin.Android ネイティブのイベントから IObservable インスタンスを作成するための多くの拡張メソッドが含まれます。|
|ReactiveProperty.XamariniOS|![](https://img.shields.io/nuget/v/ReactiveProperty.XamariniOS.svg)![](https://img.shields.io/nuget/dt/ReactiveProperty.XamariniOS.svg)|ReactiveProperty と ReactiveCommand を Xamarin.iOS ネイティブ コントロールにバインドするための多くの拡張メソッドが含まれます。|
63 changes: 63 additions & 0 deletions docs/docs-ja/advanced/awaitable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Awaitable

`ReactiveProperty`(`ReactivePropertySlim` を含む)、`ReadOnlyReactiveProperty`(`ReadOnlyReactivePropertySlim` を含む)、`ReactiveCommand` では `await` 演算子を使用できます。
`await` 演算子を使用すると、次の値が発行されるまでプログラムは待機します。

## 例:

```csharp
// CancellationTokenSource を持つ View
public partial class SampleWindow : Window
{
CancellationTokenSource cts;
SampleViewModel viewModel;

public SampleWindow()
{
InitializeComponent();
cts = new CancellationTokenSource();
viewModel = new SampleViewModel(cts.Token);
}

protected override void OnClosed(EventArgs e)
{
// 終了時に、すべての await をキャンセルします。
cts.Cancel();
cts.Dispose();

base.OnClosed(e);
}
}

// CancellationToken を持つ ViewModel
public class SampleViewModel
{
public ReactiveCommand MyCommand { get; private set; }
public ReactiveProperty<int> ClickCount { get; private set; }

public SampleViewModel(CancellationToken closeToken)
{
MyCommand = new ReactiveCommand();
ClickCount = new ReactiveProperty<int>();

// async/await でイベントを処理します。
SubscribeAsync(closeToken);
}

async void SubscribeAsync(CancellationToken closeToken)
{
using (var handler = MyCommand.GetAsyncHandler(closeToken))
{
while (true)
{
await handler; // クリックされるまで await します。
ClickCount.Value += 1;
}
}
}
}
```

複数回 await する場合は、`GetAsyncHandler` から `ObservableAsyncHandler<T>` を取得してください。これは割り当てなしで複数回 await できます。1 回だけ await する場合は、`await command.WaitUntilValueChangedAsync(token)` を使用できます。

> 注: `ReactiveProperty` を直接 await することもできますが、`GetAsyncHandler`(複数回の await)または `WaitUntilValueChangedAsync`(1 回限り)を使用し、`CancellationToken` を渡すことを推奨します。
Loading
Loading