Skip to content

Commit

Permalink
breaking change: Make Bind use non-generic IViewFor (#3676)
Browse files Browse the repository at this point in the history
<!-- Please be sure to read the
[Contribute](https://github.com/reactiveui/reactiveui#contribute)
section of the README -->

**What kind of change does this PR introduce?**
<!-- Bug fix, feature, docs update, ... -->

Fix for #3644

**What is the current behavior?**
<!-- You can also link to an open issue here. -->

BindCommand requires a view inherited from `IViewFor<TViewModel>`
ReactiveUserControl inherits `IViewFor<TViewModel>` which requires
Generics which WinForms does not work well with.

**What is the new behavior?**
<!-- If this is a feature change -->

Add BindCommandNonGeneric this is to avoid the request of not changing
the existing code, therefore adding to the available options.
NOTE: Bind only requires `IViewFor` and `IViewFor<TViewModel>` inherits
`IViewFor` therefore would still be an API change if BindCommand were
relaxed to IViewFor in the same way as Bind, but perhaps the best route.

add ReactiveUserControlNonGeneric for WinForms -  inherits `IViewFor`

**What might this PR break?**

Non due to new functions

**Please check if the PR fulfills these requirements**
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)

**Other information**:
  • Loading branch information
ChrisPulman committed Nov 23, 2023
1 parent 45a92af commit 246e8ef
Show file tree
Hide file tree
Showing 16 changed files with 487 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public class CommandBinderImplementation : Splat.IEnableLogger
{
Expand All @@ -104,6 +116,14 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public static class ComparerChainingExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public class CommandBinderImplementation : Splat.IEnableLogger
{
Expand All @@ -104,6 +116,14 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public static class ComparerChainingExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public class CommandBinderImplementation : Splat.IEnableLogger
{
Expand All @@ -104,6 +116,14 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public static class ComparerChainingExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public static ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(this TView view, TViewModel? viewModel, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> propertyName, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlName, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public class CommandBinderImplementation : Splat.IEnableLogger
{
Expand All @@ -102,6 +114,14 @@ namespace ReactiveUI
where TView : class, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.IObservable<TParam?> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
public ReactiveUI.IReactiveBinding<TView, TProp> BindCommandNonGeneric<TView, TViewModel, TProp, TControl, TParam>(TViewModel? viewModel, TView view, System.Linq.Expressions.Expression<System.Func<TViewModel, TProp?>> vmProperty, System.Linq.Expressions.Expression<System.Func<TView, TControl>> controlProperty, System.Linq.Expressions.Expression<System.Func<TViewModel, TParam?>> withParameter, string? toEvent = null)
where TView : class, ReactiveUI.IViewFor
where TViewModel : class
where TProp : System.Windows.Input.ICommand { }
}
public static class ComparerChainingExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace ReactiveUI.Winforms
public PlatformOperations() { }
public string? GetOrientation() { }
}
public class ReactiveUserControlNonGeneric : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor
{
public ReactiveUserControlNonGeneric() { }
protected override void Dispose(bool disposing) { }
}
public class ReactiveUserControl<TViewModel> : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace ReactiveUI.Winforms
public PlatformOperations() { }
public string? GetOrientation() { }
}
public class ReactiveUserControlNonGeneric : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor
{
public ReactiveUserControlNonGeneric() { }
protected override void Dispose(bool disposing) { }
}
public class ReactiveUserControl<TViewModel> : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace ReactiveUI.Winforms
public PlatformOperations() { }
public string? GetOrientation() { }
}
public class ReactiveUserControlNonGeneric : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor
{
public ReactiveUserControlNonGeneric() { }
protected override void Dispose(bool disposing) { }
}
public class ReactiveUserControl<TViewModel> : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ namespace ReactiveUI.Winforms
public PlatformOperations() { }
public string? GetOrientation() { }
}
public class ReactiveUserControlNonGeneric : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor
{
public ReactiveUserControlNonGeneric() { }
protected override void Dispose(bool disposing) { }
}
public class ReactiveUserControl<TViewModel> : System.Windows.Forms.UserControl, ReactiveUI.IActivatableView, ReactiveUI.IViewFor, ReactiveUI.IViewFor<TViewModel>
where TViewModel : class
{
Expand Down
23 changes: 23 additions & 0 deletions src/ReactiveUI.Winforms/ReactiveUserControlNonGeneric.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions src/ReactiveUI.Winforms/ReactiveUserControlNonGeneric.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2023 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Windows.Forms;

namespace ReactiveUI.Winforms;

/// <summary>
/// This is an UserControl that is both and UserControl and has a ReactiveObject powers
/// (i.e. you can call RaiseAndSetIfChanged).
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
/// <seealso cref="ReactiveUI.IViewFor" />
public partial class ReactiveUserControlNonGeneric : UserControl, IViewFor
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveUserControlNonGeneric"/> class.
/// </summary>
public ReactiveUserControlNonGeneric() => InitializeComponent();

/// <inheritdoc/>
object? IViewFor.ViewModel { get; set; }

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
components?.Dispose();
}

base.Dispose(disposing);
}
}
Loading

0 comments on commit 246e8ef

Please sign in to comment.