Xaml 入门级 MVVM 数据绑定

Xaml Entry MVVM Databinding

我正在尝试将 Xaml 中的条目连接到 ViewModel。 问题是条目不会触发 PropertyChanged 事件。

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

Consturter 使用值初始化条目,这会触发 PropertyChanged,但是当我在文本字段中输入内容时,显示的字段会更改,但不会触发 PropertyChanged... 我知道我可以在视图中使用 OnEntryTextChanged 事件,但我想使用数据绑定来获取 "perfect"MVVM。有可能实现吗?

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

在你的 PowersViewModel 中你正在做:-

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

这样,您对 Entry 所做的任何更改都不会存储回您的 ViewModel

如果将此 属性 更改为:-

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

您会看到更改已保存在您的 ViewModel 中。

尝试下面的示例,该示例还显示一个 Button,您可以单击它来检查 ViewModel 中的值,它会显示实际值的警报。如果将 private set 更改为 set,您将看到显示的消息,显示 Entry 控件中显示的当前正确值。

例子:-

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

支持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;
        }
    }
}