Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding 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 several examples with WPF but no examples with Windows Forms.

EDIT: Part 1: Bind the selected value to Following example from comment:

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

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

Part 2: Bind the items in the ComboBox to a collection in the viewmodel ? Don't know how to do

like image 483
AIDANDan Avatar asked Dec 17 '15 14:12

AIDANDan


2 Answers

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

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

EDIT: I have create 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; }
    }
}
like image 126
ds-b Avatar answered Sep 28 '22 23:09

ds-b


You can use the Observable.FromEventPattern method to bind the firing of the SelectedIndexChanged event to your 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);
like image 39
C. Augusto Proiete Avatar answered Sep 28 '22 22:09

C. Augusto Proiete