如何强制更新只读 属性?
How to force update on a read only property?
我正在尝试自动计算我的对象的总价值。
假设我的对象是:
public class Sale
{
public double Amount { get; set; }
public double Price { get; set; }
public double Total { get { return Amount * Price; } }
}
我的页面上有两个 Entry
,因此用户可以键入 Amount
和 Price
值,以及一个 Label
来显示 Total
值:
<Entry Placeholder="Amount"
ReturnType="Done"
Keyboard="Numeric"
Text="{Binding MySale.Amount, Mode=OneWayToSource, StringFormat='{}{0:N0}'}"/>
<Entry Placeholder="Price"
ReturnType="Done"
Keyboard="Numeric"
Text="{Binding MySale.Price, Mode=OneWayToSource, StringFormat='{}{0:N0}'}"/>
<Label Text="{Binding MySale.Total, StringFormat='{}R$ {0:N2}'}"/>
BindingContext
被正确定义为我的视图模型,MySale
对象实现了 INotifyPropertyChanged
:
private Sale _mySale;
public Sale MySale
{
get { return _mySale; }
set { SetProperty(ref _mySale, value); } // The SetProperty is defined in my BaseViewModel
}
问题是当我更改条目的值时,标签的值没有更新。当控件未聚焦时,我什至尝试手动将 Amount
和 Price
值分配给条目文本,但它也没有用。
我不确定它是否改变了什么,但我的应用程序是一个 MVVM Xamarin.Forms 应用程序。
-- 编辑 --
这是我的 BaseViewModel
class:
public class BaseViewModel : INotifyPropertyChanged
{
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(storage, value))
return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
}
当您设置 Amount
或 Price
的值时,您可以引发多个 PropertyChanged
事件
public class Sale : BaseViewModel
{
private double amount;
private double price;
public double Amount
get { return amount; }
set { SetProperty(ref amount, value);
this.OnPropertyChanged("Total"); }
public double Price
get { return price; }
set { SetProperty(ref price, value);
this.OnPropertyChanged("Total"); }
public double Total { get { return Amount * Price; } }
}
我正在尝试自动计算我的对象的总价值。 假设我的对象是:
public class Sale
{
public double Amount { get; set; }
public double Price { get; set; }
public double Total { get { return Amount * Price; } }
}
我的页面上有两个 Entry
,因此用户可以键入 Amount
和 Price
值,以及一个 Label
来显示 Total
值:
<Entry Placeholder="Amount"
ReturnType="Done"
Keyboard="Numeric"
Text="{Binding MySale.Amount, Mode=OneWayToSource, StringFormat='{}{0:N0}'}"/>
<Entry Placeholder="Price"
ReturnType="Done"
Keyboard="Numeric"
Text="{Binding MySale.Price, Mode=OneWayToSource, StringFormat='{}{0:N0}'}"/>
<Label Text="{Binding MySale.Total, StringFormat='{}R$ {0:N2}'}"/>
BindingContext
被正确定义为我的视图模型,MySale
对象实现了 INotifyPropertyChanged
:
private Sale _mySale;
public Sale MySale
{
get { return _mySale; }
set { SetProperty(ref _mySale, value); } // The SetProperty is defined in my BaseViewModel
}
问题是当我更改条目的值时,标签的值没有更新。当控件未聚焦时,我什至尝试手动将 Amount
和 Price
值分配给条目文本,但它也没有用。
我不确定它是否改变了什么,但我的应用程序是一个 MVVM Xamarin.Forms 应用程序。
-- 编辑 --
这是我的 BaseViewModel
class:
public class BaseViewModel : INotifyPropertyChanged
{
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(storage, value))
return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
}
当您设置 Amount
或 Price
的值时,您可以引发多个 PropertyChanged
事件
public class Sale : BaseViewModel
{
private double amount;
private double price;
public double Amount
get { return amount; }
set { SetProperty(ref amount, value);
this.OnPropertyChanged("Total"); }
public double Price
get { return price; }
set { SetProperty(ref price, value);
this.OnPropertyChanged("Total"); }
public double Total { get { return Amount * Price; } }
}