2017-02-12 1 views
3

Ich habe meine erste Mono-Anwendung auf einem Raspberry Pi ausgeführt. Das Problem besteht darin, dass die Datenbindung die Benutzeroberfläche nicht aktualisiert hat. Um genauer zu sein, ist das PropertyChanged-Ereignis in meinem Controller/Modell null. Das heißt, es gibt keinen Abonnenten.Winforms Datenbindung und INotifyPropertyChanged auf Mono

Wenn ich die Anwendung auf Windows innerhalb des Visual Studio Debugger ausführen, wird die UI ordnungsgemäß aktualisiert.

Mono-Version: 4.6.2 OS: Raspbian Wheezy .NET: 4.5

Ich habe nicht viele Informationen über dieses Szenario gefunden. Da es unter Windows funktioniert und mono die INotifyPropertyChanged-Schnittstelle unterstützt, ging ich davon aus, dass es auch in Mono unter Linux läuft.

// creating the binding in code dhtControl.labelName.DataBindings.Add("Text", dht, "Name");

Ich glaube, es gibt keinen anderen Code ist erforderlich, da es die Standardimplementierung INotifyPropertyChanged ist. Der einzige Unterschied besteht darin, dass ich eine Aktion (control.Invoke) an das Modell übergebe, um das Update im Hauptthread aufzurufen.

Grüße

+0

Haben Sie das herausgefunden? Ich stoße auf dasselbe Problem. – Kohanz

+0

Ich habe festgestellt, dass beim Hinzufügen von Datenbindungen sie nicht mit Mono zum PropertyChangedEvent registriert werden, sondern mit .Net. Noch immer keine Ahnung warum. – soulsource

Antwort

0

ich das gleiche Problem haben, lösen eine Aktion Veranstaltung der Ansichtsmodell gefeuert Zugabe, in dem alle Steuerelemente aktualisieren:

internal void InvokeUIControl(Action action) 
    { 
     // Call the provided action on the UI Thread using Control.Invoke() does not work in MONO 
     //this.Invoke(action); 

     // do it manually 
     this.lblTemp.Invoke(new Action(() => this.lblTemp.Text = ((MainViewModel)(((Delegate)(action)).Target)).Temperature)); 
     this.lblTime.Invoke(new Action(() => this.lblTime.Text = ((MainViewModel)(((Delegate)(action)).Target)).Clock));   
    } 
0

ich einen Unterschied zwischen .NET und Mono bemerkt hatte und ich habe das gleiche Problem. .NET und Mono-Quellcode Nach einem Vergleich erscheint es zunächst, dass, wenn Sie eine Benachrichtigung in property ViewForm jede Control.TextChanged Sie sich zuerst in Ihrem Modell erhalten haben wollen:

public event PropertyChangedEventHandler PropertyChanged; 
    public event EventHandler TextChanged; 

    protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      if (propertyName == "Text") 
      { 
       TextChanged?.Invoke(this, EventArgs.Empty); 
      } 
     } 
    } 

Es ist wichtig, dass der Ereignishandler den Namen „Textchanged "um einen TextChanged zu benachrichtigen. Dann noch in Ihrem Modell können Sie einstellen:

private string _Text = ""; 
    public string Text { 
     get { 
      return _Text; 
     } 
     set { 
      if (_Text != value) { 
       NotifyPropertyChanged ("Text"); 
      } 
     } 
    } 

Und jetzt, Sie in Ihrer Ansicht nach so etwas tun können.

using System; 
using System.ComponentModel; 
using System.Windows.Forms; 

namespace EventStringTest 
{ 
    public partial class Form1 : Form 
    { 
     Model md = Model.Instance; 

     public Form1() 
     { 
      InitializeComponent(); 
      textBox1.DataBindings.Add("Text", md, "Text", false 
       , DataSourceUpdateMode.OnPropertyChanged); 
      this.OnBindingContextChanged(EventArgs.Empty); 
      textBox1.TextChanged += (object sender, System.EventArgs e) => { }; 
     } 

     private void Form1_Load(object sender, EventArgs evt) 
     { 
      md.PropertyChanged += (object s, PropertyChangedEventArgs e) => { }; 

      // This is just to start make Text Changed in Model. 
      md.TimerGO(); 
     } 
    } 
} 

Dies scheint eine Menge Code, aber ich suche immer noch eine elegante, noch bessere Lösung.

Verwandte Themen