2015-12-17 3 views
5

Ich möchte eine Eigenschaft in meinem Viewmodel an eine ComboBox in einer Windows Forms-Anwendung binden, die ReactiveUI verwendet.Bindung an ComboBox mit ReactiveUI und Windows Forms

Ich habe mehrere Beispiele mit WPF, aber keine Beispiele mit Windows Forms gefunden.

EDIT: Teil 1: Binden Sie den gewählten Wert zu folgende Beispiel aus Kommentar:

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

ich den Fehler: CS1955 Non-invocable member 'Component.Events' cannot be used like a method.

Teil 2: die Elemente in der ComboBox zu einer Sammlung binden im viewmodel ? Sie wissen nicht, wie

Antwort

2

Sie verwenden die Methode Observable.FromEventPattern, um die Auslösung des Ereignisses SelectedIndexChanged an Ihre Ansichtsmodelleigenschaft zu binden.

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); 
4

Erstes zu tun, sollten Sie Ihre Ansicht IViewFor<YourViewModel>-Schnittstelle implementieren und dann

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

EDIT: erstelle ich eine Demo-Projekt:

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; } 
    } 
} 
+0

Dank mate. Ich bekomme einen Fehler, wenn ich das versuche ... Was fehlt mir? (siehe aktualisierte Frage) – AIDANDan

+0

'Install-Paket reactiveui-events-winforms';) –

+0

Nochmals vielen Dank, aber dieses Paket scheint nicht Teil von ReactiveUI zu sein ... Ich kann nur Pakete verwenden, die vom Kernteam verwaltet werden. Irgendeine Idee, wie man das mit den Paketen macht, die das Kernteam veröffentlicht? – AIDANDan

0

Ihr initiales vm.SelectedItem ist null und es gibt noch keine Änderung, um die VM aus der Ansicht zu aktualisieren. Legen Sie eine erste Auswahl im VM-Konstruktor fest.

0

Ein paar Ideen zur Verbesserung der Liste der Werte beziehen:

  1. den direkten Satz von comboBox1.DataSource = ViewModel.Items; mit einer Bindung ersetzen OneWayBind(ViewModel, vm => vm.Items, v => v.comboBox1.DataSource); so dass es nicht notwendig für ViewModel ist in der Ansicht Konstruktor existieren und ViewModel kann dynamisch geändert werden.
  2. Verwenden Sie ReactiveBindingList anstelle von ReactiveList, damit WinForms-Bindung auf Änderungen in der Werteliste reagieren kann (obwohl ich dies für dieses genaue Szenario nicht versucht habe).