我正在阅读这个http://msdn.microsoft.com/en-us/magazine/jj651572.aspx来学习mvvm轻型框架。 我下载了源代码Friend.cs。
我的问题是为什么不同属性的某些set方法的实现方式不同。
例如,名字的setter是,为什么我需要_firstName的'ref'关键字。
Set(FirstNamePropertyName, ref _firstName, value);
DateOfBirthString的setter是“
RaisePropertyChanged(() => DateOfBirth);
何时会评估linq表达式?
namespace MyFriends.Model
{
[SimpleSerialize]
public class Friend : ObservableObject
{
/// <summary>
/// The <see cref="FirstName" /> property's name.
/// </summary>
public const string FirstNamePropertyName = "FirstName";
private string _firstName;
/// <summary>
/// Sets and gets the FirstName property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
[SimpleSerialize(FieldName = "first_name")]
public string FirstName
{
get
{
return _firstName;
}
set
{
Set(FirstNamePropertyName, ref _firstName, value);
}
}
/// <summary>
/// The <see cref="LastName" /> property's name.
/// </summary>
public const string LastNamePropertyName = "LastName";
private string _lastName;
/// <summary>
/// Sets and gets the LastName property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
[SimpleSerialize(FieldName = "last_name")]
public string LastName
{
get
{
return _lastName;
}
set
{
Set(LastNamePropertyName, ref _lastName, value);
}
}
/// <summary>
/// The <see cref="DateOfBirth" /> property's name.
/// </summary>
public const string DateOfBirthPropertyName = "DateOfBirth";
private string _dateOfBirthString;
/// <summary>
/// Sets and gets the DateOfBirth property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
[SimpleSerialize(FieldName = "birthday")]
public string DateOfBirthString
{
get
{
return _dateOfBirthString;
}
set
{
_dateOfBirthString = value;
RaisePropertyChanged(() => DateOfBirth);
}
}
public DateTime DateOfBirth
{
get
{
if (string.IsNullOrEmpty(_dateOfBirthString))
{
return DateTime.MinValue;
}
return DateTime.ParseExact(DateOfBirthString, "d", CultureInfo.InvariantCulture);
}
set
{
_dateOfBirthString = value.ToString("d", CultureInfo.InvariantCulture);
}
}
private string _imageUrl;
[SimpleSerialize(FieldName = "picture")]
public string ImageUrl
{
get
{
return _imageUrl;
}
set
{
_imageUrl = value;
RaisePropertyChanged(() => ImageUri);
}
}
public Uri ImageUri
{
get
{
return new Uri(_imageUrl);
}
}
}
}
答案 0 :(得分:2)
这两种方法之间的区别在于Set
方法替换_firstName
字段的旧值,然后引发PropertyChanged
事件,而RaisePropertyChanged
只引发PropertyChanged
Set
事件。
在大多数情况下,您希望使用value
方法,因为它通过在一个方法中包含通常需要在属性的setter中完成的所有操作来缩短属性声明:
PropertyChanged
的内容覆盖它,然后ref _firstName
事件以通知有关此更新的视图。该字段需要通过引用传递(因此使用Set
)的原因是,RaisePropertyChanged
方法中不需要字段的内容,但字段本身实际上已更新
当一个属性的更新也影响其他属性时,RaisePropertyChanged
方法很有用。在这种情况下,这些属性&#39;内容需要手动更新,然后可以调用{{1}}方法来通知Views实际更改了哪些属性。
答案 1 :(得分:0)
我发现一个实例Set(ref _prop,value) 当您需要重新发送更新或需要进行自定义比较时,它不起作用。设置(ref _prop,value) 会对你的_prop和值进行比较,但它可能不是你想要的。对于某些属性,我可能想要添加更多条件而不仅仅是比较,在这种情况下,我将手动设置_prop =值,然后立即提高更改;
但在大多数情况下,我使用Set(ref _prop,value)
答案 2 :(得分:0)
这是一种实际用法,其中IsRunning
是主要操作,但它还会基于IsComplete
在属性IsRunning
上发出更改通知。这样,两个属性都会发送通知,而无需撤消额外的编码。
private bool _IsRunning;
public bool IsRunning
{
get => _IsRunning;
set
{
SetProperty(ref _IsRunning, value);
RaisePropertyChanged("IsComplete");
}
}
public bool IsComplete => !IsRunning;