【问题标题】:How to notify if a class property of a class property has changed?如何通知类属性的类属性是否已更改?
【发布时间】:2017-11-16 01:53:30
【问题描述】:

假设我的 WPF 应用程序中有两个类:

public class Radio
{
    public int Volume { get; set; }
}

public class Vehicle
{
    public Radio MusicRadio { get; set; }

    private void Explode()
    {
        if (MusicRadio.Volume == 10)
        {
           Application.Shutdown();
        }
    }
}

...其中Vehicle 有一个属性,它是Radio 类的一个实例。在我后面的代码中,我想在单击按钮时设置该收音机类的音量:

private void startButton_Click(object sender, TextChangedEventArgs e)
{
    Vehicle Xterra = new Vehicle() { MusicRadio = new Radio() };

    for (int i = 0; i < 666; i++)
    {
        Xterra.MusicRadio.Volume = i;
    }
}

在上述代码中,一旦 for 循环达到 10 次迭代,应用程序应通过 Explode() 方法关闭。

我希望我的Vehicle 类在每次MusicRadio 属性更改时执行其私有函数Explode()。如何确保它收到此更改的警报?

【问题讨论】:

  • 使用 Java 还是 C#?代码看起来像 C#...什么是 GUI?窗体? HTML/ASP/MVC?
  • @AustinFrench 抱歉,我已更新以修复语法并更加清晰。它是 C# 和 WPF。
  • 请修正您的帖子,使叙述与代码匹配。你写像 "Radio 是类 Vehicle""Xterra 类的成员来执行它的私有函数 Explode()",但是在您发布的代码,Radio 是一个独立类,不是Vehicle 的成员,Explode() 方法是Vehicle 的成员,而不是Xterra 的成员。 Xterra 甚至不是上面代码中的一个类。
  • 也就是说,如果您使用的是 WPF,您当然应该熟悉INotifyPropertyChanged,这似乎适用于这里。或者只是为MusicRadio 属性编写一个显式设置器,在其中调用Explode()。请改进问题,以便提供一个好的答案。
  • 你对收音机和车辆类都有完全的控制权吗?

标签: c# wpf oop events


【解决方案1】:

执行此操作的一种方法是将VolumeChanged 事件添加到您的Radio 类。然后在您的Vehicle 课程中,您可以订阅该事件并从那里调用Explode注意我没有使用过 wpf,我只是假设它会在那里工作。如果不是这样,很高兴删除答案。

首先,将事件添加到 Radio 类中:

public class Radio
{
    private int volume;

    public int Volume
    {
        get { return volume; }
        set
        {
            if (value == volume) return;
            volume = value;
            OnVolumeChanged(new EventArgs());
        }
    }

    public event EventHandler VolumeChanged;

    protected virtual void OnVolumeChanged(EventArgs e)
    {
        VolumeChanged?.Invoke(this, e);
    }
}

然后,在 Vehicle 类中订阅它,并从那里调用 Explode(或将 Explode 代码直接移动到事件中):

public class Vehicle
{
    private Radio musicRadio;

    public Radio MusicRadio
    {
        get { return musicRadio; }
        set
        {
            musicRadio = value;
            if (musicRadio != null)
            {
                // In the unlikely event that the same radio is assigned more than once, 
                // we only want to subscribe to the event one time, so remove it first.
                musicRadio.VolumeChanged -= MusicRadio_VolumeChanged;
                musicRadio.VolumeChanged += MusicRadio_VolumeChanged;
            }
        }
    }

    private void MusicRadio_VolumeChanged(object sender, EventArgs e)
    {
        Explode();
    }

    private void Explode()
    {
        if (MusicRadio.Volume == 10)
        {
            Application.Shutdown();
        }
    }
}

【讨论】:

    【解决方案2】:

    WPF MVC

    视图模型:

    public abstract class ObservableObject : INotifyPropertyChanged, INotifyDataErrorInfo
        {
            public void OnPropertyChanged<T>(Expression<Func<T>> property)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(property.GetMemberInfo().Name));
                }
            }
    }
    
    
    public class TankModel : ObservableObject
    {
      public float Level
            {
                get { return level; }
                set
                {
                    try
                    {
                        if (level != value)
                        {
                            level = value;
                            OnPropertyChanged(() => Level);
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error(ex);
                    }
                }
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 2015-09-18
      相关资源
      最近更新 更多