Xaml Entry MVVM数据绑定

时间:2016-02-18 00:08:11

标签: c# xaml mvvm data-binding xamarin.forms

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

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

Consturter使用Value初始化Entry,它会触发PropertyChanged,但是当我在Textfield中输入显示的字段更改但PropertyChanged未被触发时...... 我知道我可以在视图中使用OnEntryTextChanged事件,但我想使用数据绑定来获得“完美”的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));
        }
    }
}

1 个答案:

答案 0 :(得分:2)

在你正在做的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 PowersViewModel : BaseViewModel
{
    double baseValue = 4;
    public PowersViewModel()
    { BaseValue = baseValue; }
    public double BaseValue
    {
        //private set - incorrect!
        set
        {
            SetProperty(ref baseValue, value);
        }
        get
        {
            return baseValue;
        }
    }
}

支持班级: -

Id     Name     Designation
1      aaa      bbb
2      ccc      ddd
3      eee      fff