定制对象中属性的显式设置器 [英] Explicit setter for properties within custom object

查看:103
本文介绍了定制对象中属性的显式设置器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的自定义对象提供一个显式的设置器:

I would like to have an explicit setter for my custom object:

字符类

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

Main.razor

Main.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
    }
  }
}

我的问题是,当前代码中的设置器没有运行,因为它正在调用HP和MP设置器.更改HP和MP时,是否可以在代码内调用设置器?

My problem is that currently the setter within code doesn't run because it's calling the HP and MP setters. Is there a way to call the setter within code when I change HP and MP?

推荐答案

简而言之:否.由于绑定到Character.HPCharacter.MP,所以您没有更改属性Character,而是仅更改了模型绑定该对象的值直接.如果您这样做是一样的:

In short: No. Since you bind to Character.HP and Character.MP, you are not changing the property Character but instead the model binding only changes that object’s values directly. The same would be true if you did something like this:

// setter is called for this:
this.Character = new CharacterModel();

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

之所以这样做,是因为它在功能上等同于以下内容:

The reason for this is because it is functionally equivalent to the following:

// 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界面,让其将有关属性更改的信息通知相关方:

If you need to find out when a property of the character model is changed, then you could follow the approach that is usually used in MVVM setups. You could have the CharacterModel implement the INotifyPropertyChanged interface, having it notify interested parties of property changes:

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));
}

是的,不幸的是,这给您的模型类型增加了很多膨胀,但从积极的方面来说,它现在已经完全反应了.因此,您可以订阅对其属性的更改:

Yes, this unfortunately adds a lot of bloat to your model type but on the plus side it is now fully reactive. So you can subscribe to changes to its properties:

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()
        }
    }
}

这篇关于定制对象中属性的显式设置器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆