257 lines
7.2 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|