Skip to content

Commit c9645bb

Browse files
authored
build(deps): bump ReactiveUI.Binding to 8.3.0 (#4520)
## Summary **ReactiveUI now brings ReactiveUI.Binding 8.3.0, which reads members ReactiveUI.SourceGenerators writes.** - Bump `BindingVersion` to 8.3.0 in `src/Directory.Packages.props`, covering `ReactiveUI.Binding` and `ReactiveUI.Binding.Reactive`. - README: drop the advice to use a `[Reactive]` partial property for anything passed to `WhenAnyValue` (Binding 8.3.0 fixes that gap), and mention the new diagnostic RXUIBIND021 where the README covers Binding's analyzers. - Fix a real RXUIBIND021 hit the new analyzer found in `ReactiveUI.Samples.Maui`: `Username`, `Password`, `LoginButton` and `CancelButton` are fields the MAUI XAML compiler writes into `LoginPage`, not members ReactiveUI.SourceGenerators writes, so `Bind`/`BindCommand` had no generated binding for them. Switch those four calls to `BindUnsafe`/`BindCommandUnsafe`, and convert `LoginViewModel`'s hand-rolled `UserName`/`Password` properties to `[Reactive]` partial properties. ## Why Picks up ReactiveUI.Binding 8.3.0, whose source generator now writes bindings for `[Reactive]` fields and partial properties, `[ReactiveCollection]`, `[BindableDerivedList]`, `[ReactiveCommand]` and `[IReactiveObject]` members that ReactiveUI.SourceGenerators adds. Building the repo against it with `-warnaserror` surfaced one real RXUIBIND021 case, fixed above. ## Breaking changes None. ## How this was verified Full solution build with `-warnaserror` is clean on every target framework, including the Windows-only ones cross-compiled on Linux. Built and ran every test project and the Windows-only examples (WPF, WinForms, WinUI, MAUI) on a real Windows host, including the fixed `ReactiveUI.Samples.Maui`. Ran the documentation example output checks against every example project that runs on Linux; all match their expected output. `ReactiveUI.Device.Tests` was not run; it needs an emulator, per this repo's own CI split. ## Notes for the reviewer The `Directory.Packages.props` change only touches `BindingVersion`, to avoid a merge conflict with the concurrent `ReactiveUI.SourceGenerators` version bump on another branch. The `ReactiveUI.Samples.Maui` fix is the only behavior change outside dependency and doc updates; the rest is mechanical. ## Checklist - [x] I have read the [Contribute guide](https://www.reactiveui.net/contribute/index.html) - [x] The PR title follows [Conventional Commits](https://www.conventionalcommits.org/) - [x] Tests cover this change, or the summary says why they do not - [ ] New or changed public API has XML documentation
1 parent a4baf2a commit c9645bb

4 files changed

Lines changed: 18 additions & 20 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,14 @@ your project references and write code for that flavour.
147147

148148
- **Remove your own reference to ReactiveUI.SourceGenerators**, or set it to the version ReactiveUI brings or later.
149149
An older version fails to restore with error NU1605.
150-
- **Use a partial property for any property you pass to `WhenAnyValue`.** `[Reactive]` also works on a field, but
151-
ReactiveUI.Binding cannot see a property the generators write from a field. A `WhenAnyValue` call on that property
152-
throws at run time.
153150

154151
### Analyzers
155152

156153
An **analyzer** checks your code as you type and reports problems as warnings or errors. ReactiveUI.Binding and
157154
ReactiveUI.SourceGenerators run their analyzers in your project. They report binding calls and attributes that the
158-
generators cannot handle.
155+
generators cannot handle. Diagnostic RXUIBIND021 flags a binding call with no generated binding behind it, such as
156+
one that targets a member another source generator adds or a stored lambda; that call throws at run time, so treat
157+
the warning as a bug to fix rather than suppress.
159158

160159
The analyzers inside ReactiveUI.Primitives stay out of your project. ReactiveUI references ReactiveUI.Primitives with
161160
`ExcludeAssets="analyzers"`. To use them, reference ReactiveUI.Primitives directly:

‎src/Directory.Packages.props‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<PropertyGroup Label="Shared Version Variables">
88
<SplatVersion>21.0.0SplatVersion>
99
<PrimitivesVersion>8.2.0PrimitivesVersion>
10-
<BindingVersion>8.2.0BindingVersion>
10+
<BindingVersion>8.3.0BindingVersion>
1111
<TUnitVersion>1.69.16TUnitVersion>
1212

‎src/examples/ReactiveUI.Samples.Maui/LoginPage.xaml.cs‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,20 @@ public LoginPage()
2626

2727
_ = this.WhenActivated(d =>
2828
{
29-
_ = this.Bind(ViewModel, vm => vm.UserName, v => v.Username.Text)
29+
// Username, Password, LoginButton and CancelButton are fields the MAUI XAML compiler
30+
// writes into this partial class from LoginPage.xaml, not members ReactiveUI.SourceGenerators
31+
// adds, so ReactiveUI.Binding has no generated binding for them. The Unsafe calls are the
32+
// documented fallback (RXUIBIND021) for a destination member another source generator owns.
33+
_ = this.BindUnsafe(ViewModel, static vm => vm.UserName, static v => v.Username.Text)
3034
.DisposeWith(d);
3135

32-
_ = this.Bind(ViewModel, vm => vm.Password, v => v.Password.Text)
36+
_ = this.BindUnsafe(ViewModel, static vm => vm.Password, static v => v.Password.Text)
3337
.DisposeWith(d);
3438

35-
_ = this.BindCommand(ViewModel, vm => vm.Login, v => v.LoginButton)
39+
_ = this.BindCommandUnsafe(ViewModel, static vm => vm.Login, static v => v.LoginButton, toEvent: null)
3640
.DisposeWith(d);
3741

38-
_ = this.BindCommand(ViewModel, vm => vm.Cancel, v => v.CancelButton)
42+
_ = this.BindCommandUnsafe(ViewModel, static vm => vm.Cancel, static v => v.CancelButton, toEvent: null)
3943
.DisposeWith(d);
4044

4145
_ = ViewModel.Login

‎src/examples/ReactiveUI.Samples.Maui/LoginViewModel.cs‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
// See the LICENSE file in the project root for full license information.
55

66
using System.Diagnostics;
7+
using ReactiveUI.SourceGenerators;
78

89
namespace ReactiveUI.Samples.Maui;
910

1011
/// A view model that handles user login with reactive validation and async execution.
1112
[DebuggerDisplay("LoginViewModel UserName={UserName}")]
12-
public class LoginViewModel : ReactiveObject, IDisposable
13+
public partial class LoginViewModel : ReactiveObject, IDisposable
1314
{
1415
/// Cancellation source for the in-flight login operation, signalled by the command.
1516
private CancellationTokenSource? _loginCancellation;
@@ -52,18 +53,12 @@ public LoginViewModel(ISequencer scheduler)
5253
}
5354

5455
/// Gets or sets the user name.
55-
public string? UserName
56-
{
57-
get;
58-
set => this.RaiseAndSetIfChanged(ref field, value);
59-
}
56+
[Reactive]
57+
public partial string? UserName { get; set; }
6058

6159
/// Gets or sets the password.
62-
public string? Password
63-
{
64-
get;
65-
set => this.RaiseAndSetIfChanged(ref field, value);
66-
}
60+
[Reactive]
61+
public partial string? Password { get; set; }
6762

6863
/// Gets the login command. Returns true on success, false on failure.
6964
public ReactiveCommand<RxVoid, bool> Login { get; }

0 commit comments

Comments
 (0)