自定义对象内属性的显式setter



我想为我的自定义对象有一个显式的setter:

字符类

public class CharacterModel
{
public int HP { get; set; }
public int MP { get; set; }
}

主.razor

<input type="text" @bind-value="Character.HP" />
<input type="text" @bind-value="Character.MP" />
@code {
private CharacterModel character;
public CharacterModel Character
{
get => character;
set 
{
character = value;
// Do something else
}
}
}

我的问题是,目前代码中的setter没有运行,因为它正在调用HP和MP setter。当我更改HP和MP时,有没有方法在代码中调用setter?

简而言之:否。由于绑定到Character.HPCharacter.MP,因此不会更改属性Character,而是模型绑定仅直接更改该对象的值。如果你做了这样的事情,情况也是一样的:

// setter is called for this:
this.Character = new CharacterModel();
// setter is not called for this:
this.Character.HP = 100;
this.Character.MP = 50;

这是因为它在功能上等同于以下内容:

// getter is used to retrieve object:
var character = this.Character;
// only operates on a local reference:
character.HP = 100;
character.MP = 50;

如果您需要了解角色模型的属性何时更改,那么您可以遵循MVVM设置中通常使用的方法。您可以让CharacterModel实现INotifyPropertyChanged接口,让它通知相关方属性更改:

public class CharacterModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _hp;
public int HP
{
get => _hp;
set
{
_hp = value;
RaisePropertyChanged();
}
}
private int _mp;
public int MP
{
get => _mp;
set
{
_mp = value;
RaisePropertyChanged();
}
}
private void RaisePropertyChanged([CallerMemberName] string propertyName = "")  
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

是的,不幸的是,这给你的模特类型增加了很多膨胀,但从好的方面来看,它现在是完全被动的。因此,您可以订阅对其属性的更改:

private CharacterModel character;
public CharacterModel Character
{
get => character;
set 
{
// nothing to do if the value hasn’t changed
if (character == value)
return;
// remove existing event handler
if (character != null)
character.PropertyChanged -= HandlePropertyChanged;
// store new value
character = value;
// add event handler
if (character != null)
character.PropertyChanged += HandlePropertyChanged;
}
}
private void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(CharacterModel.HP))
{
// HP has changed, do something
InvokeAsync(async () =>
{
highlightHealthPotion = Character.HP < 20;
StateHasChanged()
}
}
}

相关内容

  • 没有找到相关文章