Work with an array of elements on the form (own class)

这一生的挚爱 提交于 2020-06-28 03:57:26

问题


Good afternoon. I started discussing this issue here, but I thought that the topic is worthy of a separate question, since I could not find the answer “from the swipe”. Panee was discussed at StaskOverflov Thanks to this decision, changes were made to the class (new full code).

Now the changed type of the class is as follows:

    class Seasonality_ProgressBar : Control

 #region --События--
        public delegate void OnValueChangedEvent(int value);
        public event OnValueChangedEvent OnValueChanged;

#endregion

Stopwatch st = new Stopwatch();
MouseButtons mb = MouseButtons.None;

public int Value
        {
            get => _value;
            set
            {
                if (value >= ValueMinimum && value <= ValueMaximum)
                {
                    _value = value;
                    Invalidate();
                }
                else
                {
                    value = _value;
                    Invalidate();
                }
                OnValueChanged?.Invoke(_value);
            }
        }

public Seasonality_ProgressBar()
{
}

protected override void OnMouseDown(MouseEventArgs e)
{
   // base.OnMouseDown(e);
    if (!st.IsRunning)
    {
        mb = e.Button;
        st.Start();

        if (e.Button == mb)
        {
            x = e.X;
            y = e.Y;
            timer.Elapsed += OnTimedEvent;
            timer.Start();
        }
    }
    base.OnMouseDown(e);
}


 private void OnTimedEvent(Object source, ElapsedEventArgs e)
 {
     timer.Stop();
     //MessageBox.Show("Сработало");
     float reultation = x - y;
     if (reultation > 0)
     {
         Value = "A";
     }
     else
     {
         Value = "B";
     }
 }

Now on the form you can subscribe to the event:

label2.Text = (-seasonality_ProgressBar1.Value).ToString();
seasonality_ProgressBar1.OnValueChanged += SomeEvent;

And the kind of SomeEvent method is:

private void SomeEvent(int value)
{
    //Use Invoke here because your event is called from another thread
    Invoke(new Action(() =>
    {
        label2.Text = (-value).ToString();
    }));
    //File.AppendAllText("log.txt", "seasonality_ProgressBar1_MouseUp\r\n");
}

@M. Artem, Thanks for the help.

My question is this. On the form of elements of this class a lot (12 pieces). Each of them should display its own value on a separate label. I'm trying to learn how to create an array of elements of the same type on a form, while they are of their own class or standard (which, as I understand it, matters), i.e. you need 2 solutions, assign values to them, read values from fields that are not standard (my class has "author" fields).

Friends, help me learn, pliz. Ready to answer all additional questions.

ready to send any add-ons.

I’m new here, criticize, lower, dominate.


回答1:


You could include this task in your custom control to show the value whenever it changes in a selected control.

➤ Add a new property of Control type, say:

class Seasonality_ProgressBar : Control
{
//...
    public Control ValueControl { get; set; }
//...
}

➤ In the setter of the Value property, check whether the ValueControl has a value and assign the Value property to it's Text property. You need to use the Invoke method here since you are using the System.Timers.Timer instead of the System.Windows.Forms.Timer!

public int Value
{
    get => _value;
    set
    {
        if (value >= ValueMinimum && value <= ValueMaximum)
        {
            _value = value;
            Invalidate();
        }
        else
        {
            value = _value;
            Invalidate();
        }
        if (ValueControl != null) Invoke(new Action(() => ValueControl.Text = value.ToString()));
        OnValueChanged?.Invoke(_value);
    }
}

➤ Rebuild.

➤ In the Form, select an instance of the Seasonality_ProgressBar and switch to the Properties window, you will see the new property listed as ValueControl.

➤ Select from the drop down the control that you want to connect it with this instance to show it's value. Say label1. Alternatively, you can set the ControlValue property in code:

seasonality_ProgressBar1.ValueControl = lable1; //or textBox1 ...etc.

➤ Run and try.




回答2:


Try something like this

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

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        const int ProgressBar_Width = 100;
        const int ProgressBar_Height = 200;
        const int Label_Width = 10;
        const int Label_Height = 20;
        const int Number_Bars = 10;
        const int MARGIN = 20;

        List<Seasonality_ProgressBar> bars = new List<Seasonality_ProgressBar>();

        public Form1()
        {
            InitializeComponent();

            for(int i = 0; i < Number_Bars; i++)
            {
                Seasonality_ProgressBar bar = new Seasonality_ProgressBar();
                bar.Left = MARGIN + i * (ProgressBar_Width + MARGIN);
                bar.Top = MARGIN + MARGIN + Label_Height;
                bar.Width = ProgressBar_Width;
                bar.Height = ProgressBar_Height;
                bar.Name = "Bar_" + i.ToString();
                this.Controls.Add(bar);
                bars.Add(bar);

                bar.highLabel = new Label();
                bar.highLabel.Left = MARGIN + i * (ProgressBar_Width + MARGIN) + (ProgressBar_Width / 2);
                bar.highLabel.Top = MARGIN;
                bar.highLabel.Width = Label_Width;
                bar.highLabel.Height = Label_Height;
                bar.highLabel.Text = i.ToString();
                bar.highLabel.BackColor = Color.Red;
                this.Controls.Add(bar.highLabel);

                bar.lowLabel = new Label();
                bar.lowLabel.Left = MARGIN + i * (ProgressBar_Width + MARGIN) + (ProgressBar_Width / 2);
                bar.lowLabel.Top = MARGIN + MARGIN + ProgressBar_Height + Label_Height + MARGIN;
                bar.lowLabel.Width = Label_Width;
                bar.lowLabel.Height = Label_Height;
                bar.lowLabel.Text = i.ToString();
                bar.lowLabel.BackColor = Color.LightBlue;
                this.Controls.Add(bar.lowLabel);

            }


        }
    }
    public class Seasonality_ProgressBar : ProgressBar
    {
        public Label highLabel { get; set; }
        public Label lowLabel { get; set; }
        public string name { get; set; }



    }
}


来源:https://stackoverflow.com/questions/62358912/work-with-an-array-of-elements-on-the-form-own-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!