【问题标题】:Generating a random numbers and using INotifyPropertyChanged to Updating UI生成随机数并使用 INotifyPropertyChanged 更新 UI
【发布时间】:2019-12-01 19:39:37
【问题描述】:

我是 C# 新手,目前正在开发一个程序。它有一个简单的 UI,有两个按钮(一个称为 on,另一个称为 off),还有一个显示结果的文本框。基本上我想要做的是,如果用户单击“on”按钮,则在与 windows 窗体不同的类上每隔一秒将使用一种方法生成随机数。并通过实现 INotifyPropertyChanged 我想让文本框知道该值已更新,因此文本框会不断更新我们的新随机数。一旦用户点击“关闭”按钮,我想停止生成随机数。

我的窗体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SWE_Assignment
{
    public partial class Monitor : Form
    {
        Patient newPatient = Patient.Instance;
        public static bool pulseRateOn = false;
        public Monitor()
        {
            InitializeComponent();

            newPatient.PropertyChanged += _PulseRate_PropertyChanged;
        }

        private void Save_Click(object sender, EventArgs e)
        {

           // newPatient.PL(newPatient.startRnd = true;);
        }

        void _PulseRate_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "PulseRate")
            {
                HeartBeat.Text = newPatient.PulseRate.ToString();
            }
        }



        private void Stop_Click(object sender, EventArgs e)
        {
            newPatient.startRnd = false;
        }
    }
}

我的病人班

namespace SWE_Assignment
{
    class Patient : INotifyPropertyChanged
    {

        private int _pulseRate;
        public bool startRnd = false;
        Random rnd = new Random();
        public int PulseRate
        {
            get { return _pulseRate; }
            set
            {
                _pulseRate = value;
                OnPropertyChanged("PL");
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string properyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(properyName));
        }

        private static Patient _instance = null;
        private static readonly object _padlock = new object();
        public static Patient Instance
        {
            get
            {
                lock (_padlock)
                {
                    if (_instance == null)
                    {
                        _instance = new Patient();
                    }
                    return _instance;
                }
            }
        }




        public void PL(bool srt)
        {
            Timer timer = new Timer();
            timer.AutoReset = true;
            timer.Interval = 1000;


            if (startRnd == true)
            {
                timer.Elapsed += PLS;
                timer.Enabled = true;
                timer.Start();
            } else
            {
                timer.Enabled = false;
                timer.Stop();
            }
        }

        private void PLS(object sender, ElapsedEventArgs e)
        {

            PulseRate = rnd.Next(100, 150);
            Console.WriteLine(PulseRate);

        }
    }
}

另外,我正在为我的患者使用单例模式,因为我只想拥有一个患者实例,以便我可以访问另一个类(称为警报)上的相同随机数,以检查它是大于还是小于某些数字。我确实意识到我的“停止”按钮有问题,因为它只会再次调用该方法并且不会停止该方法的运行。如果有人可以提供帮助,我将不胜感激。

【问题讨论】:

  • OnPropertyChanged("PL"); 属性名称是 PulseRate。 PulseRate 是您在事件处理程序中检查的内容。让它OnPropertyChanged("PulseRate");
  • Timer timer = new Timer(); - 您应该为每个患者只创建一个 Timer 实例。最好在构造函数中做到这一点。否则你会有多个 Timer 正在运行的副本
  • 谢谢,一旦我运行它并单击“开始”,我会收到以下错误 system.invalidoperationexception cross-thread operation not valid, control access from a thread but it is created.

标签: c# winforms random inotifypropertychanged


【解决方案1】:

有一些东西需要改变。

OnPropertyChanged("PL"); - 属性名称是PulseRate。 “PulseRate”是您在事件处理程序中检查的内容。让它OnPropertyChanged("PulseRate");

Timer timer = new Timer(); - 您应该为每个患者只创建一个 Timer 实例。最好在构造函数中做到这一点。否则你会有多个 Timer 正在运行的副本

可以通过 Enabled 属性来管理 Timer: 调用 Start() 方法与将Enabled 设置为true 相同。同样,调用Stop() 方法与将Enabled 设置为false 相同。

private void Stop_Click(object sender, EventArgs e)
{
    // newPatient.startRnd = false;
    newPatient.PL(false);
}

class Patient : INotifyPropertyChanged
{
    Timer timer;
    private Patient()
    {
        timer = new Timer();
        timer.AutoReset = true;
        timer.Interval = 1000;
        timer.Elapsed += PLS;
    }

    Random rnd = new Random();

    private int _pulseRate;
    public int PulseRate
    {
        get { return _pulseRate; }
        set
        {
            _pulseRate = value;
            OnPropertyChanged("PulseRate");
        }
    }

    public void PL(bool srt)
    {
        timer.Enabled = srt;
    }

    private void PLS(object sender, ElapsedEventArgs e)
    {
        PulseRate = rnd.Next(100, 150);
        Console.WriteLine(PulseRate);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string properyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(properyName));
    }

    private static Patient _instance = null;
    private static readonly object _padlock = new object();
    public static Patient Instance
    {
        get
        {
            lock (_padlock)
            {
                if (_instance == null)
                {
                    _instance = new Patient();
                }
                return _instance;
            }
        }
    }
}

【讨论】:

  • 当我在类构造函数中创建计时器时,在我的 PLS 方法中,我收到错误,即当前上下文中不存在名称“计时器”。
  • 您是否使用 this type of Timer,用于 WinForms?查看编辑 - 我添加了字段 timer
  • 谢谢,这次它给了我对象引用未设置为对象实例的错误代码。
  • 刚刚意识到我需要更改类构造函数并且不再收到有关计时器的错误,但是我得到 system.invalidoperationexception cross-thread operation not valid control 从一个线程而不是它创建的线程访问上
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
相关资源
最近更新 更多