Linking to ComboBox using ReactiveUI and Windows Forms

I would like to bind a property in my viewmodel to a ComboBox in a Windows Forms application using ReactiveUI.

I found some examples with WPF, but without examples with Windows Forms.

EDIT: Part 1: bind the selected value to the following example from the comment:

this.Bind(ViewModel, vm => vm.ViewModelProperty, v => v.comboBox.SelectedValue, comboBox.Events().SelectedValueChanged); 

I get an error: CS1955 Non-invocable member 'Component.Events' cannot be used like a method.

Part 2: Link items in a ComboBox to a collection in a viewmodel? I don’t know how to do it.

+5
source share
4 answers

You can use the Observable.FromEventPattern method to bind the triggering of the SelectedIndexChanged event to the view model property.

 comboBoxWithItems.DataSource = ViewModel.ListOfPossibleItemsProperty; comboBoxWithItems.DisplayMember = "Name"; Observable.FromEventPattern<EventHandler, EventArgs>( ev => comboBoxWithItems.SelectedIndexChanged += ev, ev => comboBoxWithItems.SelectedIndexChanged -= ev) .Select(x => comboBoxWithItems.SelectedItem) .BindTo(this, x => x.ViewModel.SelectedItemProperty); 
+2
source

First, your view should implement the IViewFor<YourViewModel> interface, and then

 this.Bind(ViewModel, vm => vm.PropertyToBind, x => comboBox.SelectedValue, comboBox.Events().SelectedValueChanged) 

EDIT : I created a demo project:

 using System; using System.Reactive.Linq; using System.Windows.Forms; using ReactiveUI; namespace WindowsFormsApplication { public partial class Form1 : Form, IViewFor<MyViewModel> { public Form1() { InitializeComponent(); ViewModel = new MyViewModel(); comboBox1.DataSource = ViewModel.Items; var selectionChanged = Observable.FromEvent<EventHandler, EventArgs>( h => (_, e) => h(e), ev => comboBox1.SelectedIndexChanged += ev, ev => comboBox1.SelectedIndexChanged += ev); this.Bind(ViewModel, vm => vm.SelectedItem, x => x.comboBox1.SelectedItem, selectionChanged); } public MyViewModel ViewModel { get; set; } object IViewFor.ViewModel { get { return ViewModel; } set { ViewModel = (MyViewModel)value; } } } public class MyItem { private readonly string _text; public MyItem(string text) { _text = text; } public override string ToString() { return _text; } } public class MyViewModel : ReactiveObject { private MyItem _selectedItem; public MyViewModel() { Items = new ReactiveList<MyItem> {new MyItem("test1"), new MyItem("test2")}; } public MyItem SelectedItem { get { return _selectedItem; } set { this.RaiseAndSetIfChanged(ref _selectedItem, value); } } public ReactiveList<MyItem> Items { get; private set; } } } 
+4
source

Your vm.SelectedItem source file is null, and there are no changes to update the virtual machine from the view so far. Set the initial selection in the designer of the virtual machine.

0
source

A few ideas for improvement related to the list of values:

  • Replace the direct set comboBox1.DataSource = ViewModel.Items; on bind OneWayBind(ViewModel, vm => vm.Items, v => v.comboBox1.DataSource); so that there is no need for the ViewModel exist inside the view constructor, and the ViewModel can be dynamically changed.
  • Use a ReactiveBindingList instead of a ReactiveList so that WinForms binding can respond to changes in the list of values ​​(although I have not tried this for this exact scenario).
0
source

Source: https://habr.com/ru/post/1238527/


All Articles