问题
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