R3Utility.ObservableCollections 0.3.0

dotnet add package R3Utility.ObservableCollections --version 0.3.0                
NuGet\Install-Package R3Utility.ObservableCollections -Version 0.3.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="R3Utility.ObservableCollections" Version="0.3.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add R3Utility.ObservableCollections --version 0.3.0                
#r "nuget: R3Utility.ObservableCollections, 0.3.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install R3Utility.ObservableCollections as a Cake Addin
#addin nuget:?package=R3Utility.ObservableCollections&version=0.3.0

// Install R3Utility.ObservableCollections as a Cake Tool
#tool nuget:?package=R3Utility.ObservableCollections&version=0.3.0                

R3Utility

Nuget downloads NuGet
A utility library for Cysharp/R3 that provides enhanced reactive programming capabilities, focusing on validation, property binding, and UI event observation.

🚨 Breaking Changes (v0.3.0)

Starting from version 0.3.0, ObservableCollectionsExtensions has been moved to a separate package: R3Utility.ObservableCollections. If you were using ObserveElementProperty, please install the new package and update your imports accordingly.

dotnet add package R3Utility.ObservableCollections
using R3Utility.ObservableCollections;

Features

Two-Way Binding Extensions

  • Convert INotifyPropertyChanged properties to BindableReactiveProperty
  • Automatic value propagation in both directions
  • Support for deep property path binding (up to 3 levels)

Reactive Validation

  • Combine multiple boolean observables with various logical operations
  • Support for creating executable command sources based on validation states

Observable Element Property Monitoring (R3Utility.ObservableCollections)

  • Observe changes in specific properties of elements within a collection.
  • Customizable option, pushCurrentValueOnSubscribe to control initial value emission.
  • Support for deep property path binding (up to 3 levels)

WinForms UI Event Observables (R3Utility.WinForms)

  • Convert common UI events into observables
  • Supports TextBox, Button, CheckBox, ComboBox, and Control drag-and-drop events

API Reference

ReactivePropertyExtensions

Method Parameters Return Type Description
ToTwoWayBindableReactiveProperty<T, TProperty> T value, Expression<Func<T, TProperty>> propertySelector BindableReactiveProperty<TProperty> Converts a single property to two-way bindable reactive property
ToTwoWayBindableReactiveProperty<T, TProperty1, TProperty2> T value, Func<T, TProperty1?> propertySelector1, Func<TProperty1, TProperty2> propertySelector2 BindableReactiveProperty<TProperty2> Converts a nested property (2 levels) to two-way bindable reactive property
ToTwoWayBindableReactiveProperty<T, TProperty1, TProperty2, TProperty3> T value, Func<T, TProperty1?> propertySelector1, Func<TProperty1, TProperty2?> propertySelector2, Func<TProperty2, TProperty3> propertySelector3 BindableReactiveProperty<TProperty3> Converts a deeply nested property (3 levels) to two-way bindable reactive property

ReactiveValidationHelper

Method Parameters Return Type Description
CombineLatestValuesAreAllFalse IEnumerable<Observable<bool>> Observable<bool> Combines multiple observables and returns true only when all source values are false
CombineLatestValuesAreAllTrue IEnumerable<Observable<bool>> Observable<bool> Combines multiple observables and returns true only when all source values are true
CombineLatestValuesAreAnyFalse IEnumerable<Observable<bool>> Observable<bool> Combines multiple observables and returns true when any source value is false
CombineLatestValuesAreAnyTrue IEnumerable<Observable<bool>> Observable<bool> Combines multiple observables and returns true when any source value is true
CreateCanExecuteSource IBindableReactiveProperty[] Observable<bool> Creates an observable that monitors HasErrors property of multiple BindableReactiveProperty instances

ObservableCollectionsExtensions(R3Utility.ObservableCollections)

Method Parameters Return Type Description
ObserveElementProperty<T, TProperty> IObservableCollection<T> source, Func<T, TProperty> propertySelector, bool pushCurrentValueOnSubscribe = true, CancellationToken cancellationToken = default Observable<PropertyPack<T, TProperty>> Observes a specific property of each element in a collection and emits its values.
ObserveElementProperty<T, TProperty1, TProperty2> IObservableCollection<T> source, Func<T, TProperty1?> propertySelector1, Func<TProperty1, TProperty2> propertySelector2, bool pushCurrentValueOnSubscribe = true, CancellationToken cancellationToken = default Observable<PropertyPack<T, TProperty2>> Observes a nested property (2 levels) in a collection and emits its values.
ObserveElementProperty<T, TProperty1, TProperty2, TProperty3> IObservableCollection<T> source, Func<T, TProperty1?> propertySelector1, Func<TProperty1, TProperty2> propertySelector2, Func<TProperty2, TProperty3> propertySelector3, bool pushCurrentValueOnSubscribe = true, CancellationToken cancellationToken = default Observable<PropertyPack<T, TProperty3>> Observes a deeply nested property (3 levels) in a collection and emits its values.

WinForms UIComponentExtensions (R3Utility.WinForms)

Method Parameters Return Type Description
TextChangedAsObservable TextBoxBase textBox Observable<EventArgs> Observes TextChanged event of a TextBoxBase.
ClickAsObservable Button button Observable<EventArgs> Observes Click event of a Button.
CheckedChangedAsObservable CheckBox checkBox Observable<EventArgs> Observes CheckedChanged event of a CheckBox.
SelectedIndexChangedAsObservable ComboBox comboBox Observable<EventArgs> Observes SelectedIndexChanged event of a ComboBox.
SelectionChangeCommittedAsObservable ComboBox comboBox Observable<EventArgs> Observes SelectionChangeCommitted event of a ComboBox.
DragEnterAsObservable Control control Observable<DragEventArgs> Observes DragEnter event of a Control.
DragOverAsObservable Control control Observable<DragEventArgs> Observes DragOver event of a Control.
DragLeaveAsObservable Control control Observable<EventArgs> Observes DragLeave event of a Control.
DragDropAsObservable Control control Observable<DragEventArgs> Observes DragDrop event of a Control.

Usage Examples

Two-Way Binding

// Create a BindableReactiveProperty<T> that is two-way bound
BindableReactiveProperty<string> name = item.ToTwoWayBindableReactiveProperty(x => x.Name);

// This will also update the Name property of the item object
name.Value = "X"; //item.Name = "X"

// This will also update the Value property of the BindableReactiveProperty
item.Name = "Y"; //name.Value = "Y"


// Deep property path binding
BindableReactiveProperty<string> nestedProperty = viewModel.ToTwoWayBindableReactiveProperty(
    x => x.User,
    x => x.Profile,
    x => x.DisplayName
);

Validation Helpers

// Combine multiple validation states
Observable<bool> isValid = ReactiveValidationHelper.CombineLatestValuesAreAllTrue(
      emailValidation,
      passwordValidation,
      termsAccepted
);

// Create executable command source
Observable<bool> canExecute = ReactiveValidationHelper.CreateCanExecuteSource(
      emailProperty,
      passwordProperty
);
command = canExecute.ToReactiveCommand();

Observing Properties in a Collection

using ObservableCollections;
using R3;
using R3Utility.ObservableCollections;

ObservableList<Item> collection = [];
Item item1 = new() { Name = "foo" };

collection.Add(item1);
var disposable = collection.ObserveElementProperty(x => x.Name, pushCurrentValueOnSubscribe: false)
                           .Subscribe(property => Console.WriteLine($"Instance:{property.Instance}, propertyName:{property.PropertyName}, Value:{property.Value}"));
        
//Changes are output. `Instance:WpfApp1.Item, propertyName:Name, Value:bar`
item1.Name = "bar";

disposable.Dispose();

Installation

dotnet add package R3Utility
dotnet add package R3Utility.ObservableCollections
dotnet add package R3Utility.WinForms

License

R3Utility is distributed under a free and open-source license. Feel free to use it in your projects!

Contributions

We welcome contributions to the R3Utility project! If you have any suggestions, bug reports, or feature requests, please feel free to open an issue or submit a pull request. We're excited to make R3Utility better together.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.3.0 40 2/3/2025