2014-12-13 6 views
6

Ich möchte einen Befehl an die Befehlseigenschaft meiner Schaltfläche binden. Dies schien ziemlich einfach zu sein, da ich dies schon oft in WPF getan habe und die Methode hier ist sehr ähnlich. Lassen Sie mich einige Code-Schnipsel zeigen.Button Befehl Bindung funktioniert nicht in Xamarin.Forms

XAML

<?xml version="1.0" encoding="UTF-8"?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     x:Class="MyApp.View.CustomPage" 
     Title="Something"> 

<ContentPage.Content> 
    <StackLayout> 
     <Button x:Name="numBtn" Text="Increase number" Command="{Binding IncreaseCommand}" /> 
     <Label x:Name="numLabel" Text="{Binding numberText}" /> 
    </StackLayout> 
</ContentPage.Content> 
</ContentPage> 

-Code-behind

public partial class CustomPage : ContentPage 
{ 
    public CustomPage() 
    { 
     InitializeComponent(); 
     BindingContext = ViewModelLocator.ViewModel(); //ViewModelLocator is singleton, gives 
                 //you a ViewModel instance 
    } 
} 

Ansichtsmodell

public ICommand IncreaseCommand { get; private set; } 
private int number; 
public string numberText { get; private set;} 

der Konstruktor:

public ViewModel() 
{ 
    IncreaseCommand = new Command (() => IncreaseExecuted()); 
    number = 0; 
    numberText = number.ToString(); 
    OnPropertyChanged (numberText); 
} 

und dann

private void IncreaseExecuted() 
{ 
    number++; 
    numberText = number.ToString(); 
    OnPropertyChanged (numberText); 
} 

Wenn ich die App mit dem Xamarin Android Player (KitKat) laufen sehe ich den Knopf, und das Etikett zu lesen 0. Dann drücke ich die Taste und es passiert nichts. Ich habe versucht zu überprüfen, was mit Haltepunkten passiert, aber die App hält nicht an, auch nicht, wenn sie sich im Konstruktor meines ViewModels befinden. Ich denke, es hat etwas mit dem Emulator zu tun. Wie auch immer, ich denke, die Bindung ist in Ordnung, da ich eine "0" auf dem Bildschirm sehen kann. Was könnte das Problem sein? Lassen Sie mich nur bei meinem ViewModelBase Klasse zeigen:

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged 
{ 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(String propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Vielleicht ist meine numberText Eigenschaft nicht aktualisiert, wenn ich OnPropertyChanged nennen? Aber ich habe die gleiche ViewModelBase-Klasse schon mehrmals benutzt und es hat immer gut funktioniert. Eine letzte Sache, meine CustomPage Seite wird in einem NavigationPage gewickelt, die ein Kind eines TabbedPage:

MainPage.xaml.cs

this.Children.Add (new NavigationPage (new CustomPage()) {Title="Something"}); 

Dies sollte nicht alles beeinflussen, aber es gibt sie nur in Fall. Also, was ist falsch an meinem Befehlsbindung? Vielen Dank im Voraus!

Antwort

5

Sie sind fast da. Sehen Sie sich Ihren Aufruf der OnPropertyChanged-Methode genau an. Sie übergeben den Wert von numberText und nicht den Namen. Wenn Sie Ihren Code ändern, um "numberText" zu übergeben, erwarte ich, dass es richtig funktioniert.

Edit: Ich sollte hinzufügen, dass der OnPropertyChanged-Aufruf im Konstruktor das gleiche Problem hat. Der Grund, warum Sie beim Start "0" sehen, ist, dass die Ansicht einfach die vorhandene Bindung verwendet, um den Wert abzurufen.

Edit 2: Jetzt, da Xamarin C# 6.0 unterstützt, können Sie den neuen Ausdruck "nameof" verwenden, der die Notwendigkeit einer hartcodierten Zeichenfolge beseitigt. Alternativ können Sie die MVVM-Klassen von MvvmCross, MvvmLight oder XLabs verwenden.

+0

Sie scheinen in diesen Tagen mein Retter zu sein! Meine zweite Frage in Folge beantwortet von dir. Ich danke dir sehr! Das war ein Anfängerfehler, ich weiß nicht, wie ich so dumm sein könnte. –

+0

Es ist sehr häufig Datenbindungsproblem. Da PropertyChangedEventArgs eine Zeichenfolge benötigt, ist es sehr einfach, Fehler zu machen.Namensänderungen aufgrund von Refactoring sind, wo ich es am häufigsten sehe. Zu diesem Zweck empfehle ich die Verwendung einer ViewModelBase-Implementierung, die einen Ausdruck als Eingabe anstelle einer Zeichenfolge verwendet und daher Buildfehler verursacht, wenn der Eigenschaftsname geändert wird, ohne auch den Ereignisauslösungscode zu aktualisieren. MvvmLight und MvvmCross liefern beides. –

+0

Ich verstehe. Gute Idee, ich werde das umsetzen. Vielen Dank! –

Verwandte Themen