Reputation:
Recently, using a lot of examples and tips (I'm learning), I managed to create my own control class for the form .Net. Full Control Code введите сюда код
If you try to explain what the feature is, then I tried to make an analogue of ProgressBar, only slightly modified. It has various methods of changing the level. One of the most interesting ones for me was the ability to press and hold the left mouse button so that the level first shifted to the specified location of the mouse, and then I was able to control it while continuing to move the mouse.
If you try to simplify the code, then the management of this process looks like this:
class Seasonality_ProgressBar : Control
Stopwatch st = new Stopwatch();
MouseButtons mb = MouseButtons.None;
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";
}
}
It can be seen that after a while the method starts on the timerю Then I tried to place an instance of this class on the form along with the label on which I wanted to reflect the value obtained at the ProgressBar. I made such calls:
private void seasonality_ProgressBar1_MouseUp(object sender, MouseEventArgs e)
{
label2.Text = (-seasonality_ProgressBar1.Value).ToString();
}
private void seasonality_ProgressBar1_MouseMove(object sender, MouseEventArgs e)
{
label2.Text = (-seasonality_ProgressBar1.Value).ToString();
}
private void seasonality_ProgressBar1_MouseDown(object sender, MouseEventArgs e)
{
//MessageBox.Show("Привет");
label2.Text = (-seasonality_ProgressBar1.OnTimedEventValue).ToString();
int A = 0;
}
private void seasonality_ProgressBar1_Click_1(object sender, EventArgs e)
{
label2.Text = (-seasonality_ProgressBar1.Value).ToString();
}
I absolutely can’t get the value output to the label when the mouse is pressed and held, without movement. The value is displayed only when released, but I don’t feel like it. I also have multiple rendering of the label (the value is apparently constantly changing).
Please help to understand, teach. Thank.
Upvotes: 0
Views: 65
Reputation: 791
The best way here is to create your event. For example
public delegate void OnValueChangedEvent(int value);
public event OnValueChangedEvent OnValueChanged;
And you need to fire it every time you change the Value property
public int Value
{
get => _value;
set
{
if (value >= ValueMinimum && value <= ValueMaximum)
{
_value = value;
}
Invalidate();
// Use '?' here to avoid Null reference exception in case your event is not subscribed
OnValueChanged?.Invoke(_value);
}
}
Then you need to subscribe to this event from the main form, another control or whatever you want.
public Form1()
{
InitializeComponent();
seasonality_ProgressBar1.OnValueChanged += SomeEvent;
}
private void SomeEvent(int value)
{
//Use Invoke here because your event is called from another thread
Invoke(new Action(() =>
{
label2.Text = value.ToString();
}));
}
Also, try to avoid using timers and any 'delay' logic you may make up unless it sounds natural for the business logic. If you really need it, there is a perfect library for an event-driven development (like UI staff)
Upvotes: 1