Files
2025-07-14 12:03:59 +02:00

257 lines
7.2 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MaterialSkin.Controls
{
public partial class MaterialUpDown : UserControl,INotifyPropertyChanged
{
private double _value;
private bool _mouseDown;
private int _direction;
public MaterialUpDown()
{
InitializeComponent();
textBox1.BackColor = SkinManager.GetApplicationBackgroundColor();
AllowDecimal = false;
AllowKeyboard=true;
}
[Browsable(false)]
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
public bool AllowDecimal { get; set; }
public bool AllowKeyboard
{
get { return _allowKeyboard; }
set
{
_allowKeyboard = value;
textBox1.ReadOnly = !_allowKeyboard || _readOnly;
}
}
public bool HideControls
{
get { return _hideControls; }
set
{
_hideControls = value;
materialIcon1.Visible = !value;
materialIcon2.Visible = !value;
}
}
public double Value
{
get { return _value; }
set
{
_value = value;
if (_value>Max)
{
_value = Max;
}
if (_value < Min)
{
_value = Min;
}
if (!AllowDecimal)
{
_value = Math.Floor(_value);
}
Action a = ()=> textBox1.Text = _value.ToString();
if (textBox1.InvokeRequired)
textBox1.Invoke(a);
else
a();
}
}
public bool ReadOnly
{
get { return _readOnly; }
set
{
_readOnly = value;
materialIcon1.Enabled = !value;
materialIcon2.Enabled = !value;
textBox1.ReadOnly = !_allowKeyboard || _readOnly;
}
}
public event PropertyChangedEventHandler PropertyChanged= delegate { };
public double Max { get; set; }
public double Min { get; set; }
public double Step { get; set; }
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.Clear(SkinManager.GetApplicationBackgroundColor());
}
private void materialIcon2_Click(object sender, EventArgs e)
{
}
private void materialIcon1_Click(object sender, EventArgs e)
{
}
private async void HoldCountDown(CancellationToken cancellationSourceToken)
{
await Task.Delay(500);
var startTime = DateTime.Now;
while (_mouseDown&&!cancellationSourceToken.IsCancellationRequested)
{
Value += Step*_direction;
await Task.Delay(100/(int)Math.Max(1,Math.Min(5,(DateTime.Now-startTime).TotalSeconds)));
}
}
private CancellationTokenSource _cancellationSource;
private bool _readOnly;
private bool _allowKeyboard;
private void materialIcon2_MouseDown(object sender, MouseEventArgs e)
{
_cancellationSource =new CancellationTokenSource();
Value += Step;
_mouseDown = true;
_direction = 1;
Task.Run(()=> HoldCountDown(_cancellationSource.Token));
}
private void materialIcon2_MouseUp(object sender, MouseEventArgs e)
{
if (_cancellationSource != null)
{
_cancellationSource.Cancel();
_cancellationSource = null;
}
_mouseDown = false;
PropertyChanged(this,new PropertyChangedEventArgs(nameof(Value)));
}
private void materialIcon1_MouseDown(object sender, MouseEventArgs e)
{
_cancellationSource = new CancellationTokenSource();
Value -= Step;
_mouseDown = true;
_direction = -1;
Task.Run(() => HoldCountDown(_cancellationSource.Token));
}
private void materialIcon1_MouseUp(object sender, MouseEventArgs e)
{
if (_cancellationSource != null)
{
_cancellationSource.Cancel();
_cancellationSource = null;
}
_mouseDown = false;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Value)));
}
private void materialIcon2_MouseLeave(object sender, EventArgs e)
{
materialIcon2_MouseUp(null,null);
}
private void materialIcon1_MouseLeave(object sender, EventArgs e)
{
materialIcon1_MouseUp(null, null);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
(e.KeyChar != '.'))
{
e.Handled = true;
return;
}
// only allow one decimal point
if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
{
e.Handled = true;
return;
}
_validate = true;
}
private CancellationTokenSource _cancellationTokenSource = null;
private bool _validate;
private bool _hideControls;
private void textBox1_Click(object sender, EventArgs e)
{
if (textBox1.ReadOnly) return;
textBox1.SelectAll();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox1_Leave(object sender, EventArgs e)
{
if (double.TryParse((sender as TextBox).Text, NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-us"), out var value))
{
if (_cancellationTokenSource != null) _cancellationTokenSource.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
Task.Run(async () =>
{
var newValue = value;
var token = _cancellationTokenSource.Token;
if (token.IsCancellationRequested) throw new OperationCanceledException();
Value = newValue;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Value)));
});
}
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
textBox1_Leave(textBox1,null);
e.Handled = true;
}
}
}
}