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;
}
}
}
我正在尝试将 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;
}
}
}