简体   繁体   中英

Xaml Entry MVVM Databinding

i`m trying to Connect Entry in the Xaml to the ViewModel. The Problem is that the Entry doesn´t fire a PropertyChanged Event.

  <Entry FontSize="Large"
         Placeholder="3"
         Keyboard="Numeric"
         Text="{Binding BaseValue, StringFormat='{0}', Mode=TwoWay}" />

The Consturter initializes the Entry with a Value, which fires an PropertyChanged, but when i enter something in the Textfield the displayed Field Changes but the PropertyChanged isn´t triggered... I konw i could use the OnEntryTextChanged event in the View but i want to use Databindings to get "perfect"MVVM. Is there an possibility to acchieve that?

class PowersViewModel: BaseViewModel
    {
     double baseValue = 4;
     public PowersViewModel()
            {BaseValue = baseValue;}
     public double BaseValue
            {
                private set
                {
                    SetProperty(ref baseValue, value);
                }
                get
                {
                    return baseValue;
                }
            }
}
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T storage, T value,
                                  [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

In your PowersViewModel you are doing:-

public double BaseValue
{
    private set
    {
        SetProperty(ref baseValue, value);
    }
    get
    {
        return baseValue;
    }
}

By doing so, any changes that you make to the Entry will not be stored back in your ViewModel .

If you change this property to:-

public double BaseValue
{
    set
    {
        SetProperty(ref baseValue, value);
    }
    get
    {
        return baseValue;
    }
}

you will see that the changes are persisted back in your ViewModel .

Try out the example below that also displays a Button that you can click to check the value in your ViewModel and it will display an alert of the actual value. If you change your private set to set you will then see that the message displayed, displays the current correct value as displayed in the Entry control.

Example:-

StackLayout objStackLayout = new StackLayout();

Entry objEntry = new Entry()
{
    FontSize = 20,
    Placeholder = "3",
    Keyboard = Keyboard.Numeric
};
//
objEntry.SetBinding(Entry.TextProperty, "BaseValue", BindingMode.TwoWay);
objStackLayout.Children.Add(objEntry);


PowersViewModel objViewModel = new PowersViewModel();

this.BindingContext = objViewModel;


Button objButton  = new Button();
objButton.Text = "Check value";
objButton.Clicked+=((o2,e2)=>
{
    DisplayAlert("",string.Format("BaseValue={0}", objViewModel.BaseValue), "OK");
});
objStackLayout.Children.Add(objButton);

Supporting Class :-

class PowersViewModel : BaseViewModel
{
    double baseValue = 4;
    public PowersViewModel()
    { BaseValue = baseValue; }
    public double BaseValue
    {
        //private set - incorrect!
        set
        {
            SetProperty(ref baseValue, value);
        }
        get
        {
            return baseValue;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM