Added counter to OK button, 5 sec default now

Add auto-close countdown timer for UNI data entry forms: implement timer logic, UI updates, and early exit handling
This commit is contained in:
Michal Buzik 2026-08-19 14:47:34 +02:00
parent d12ee008db
commit 889782068e
3 changed files with 112 additions and 24 deletions

View File

@ -76,6 +76,9 @@ namespace TBF.Rig.DataEntry.Uni
/// Set to 'true' when the form closes
public bool Completed { get { return completed; } }
bool completed;
private System.Windows.Forms.Timer autoCloseTimer;
private int autoCloseSecondsRemaining;
private string okButtonTextBeforeAutoClose;
private readonly IRegReader[] regReaders;
@ -698,6 +701,7 @@ namespace TBF.Rig.DataEntry.Uni
private void okButton_Click(object sender, EventArgs e)
{
StopAutoCloseCountdown();
UpdateWMsFromBoxes();
completed = true;
@ -1167,6 +1171,7 @@ namespace TBF.Rig.DataEntry.Uni
private void OnForceClose(object sender, EventArgs args)
{
StopAutoCloseCountdown();
DialogResult = DialogResult.Cancel;
Close();
}
@ -1339,23 +1344,62 @@ namespace TBF.Rig.DataEntry.Uni
log.Debug("Reading serial numbers DONE!");
}
public void AutoClickOkAfterDelay(int delayMs = 10000)
public void AutoClickOkAfterDelay(int delayMs = 5000)
{
_ = AutoClickInternal(okButton, delayMs);
if (delayMs <= 0 || IsDisposed || Disposing)
return;
if (InvokeRequired)
{
BeginInvoke(new Action<int>(AutoClickOkAfterDelay), delayMs);
return;
}
StopAutoCloseCountdown();
okButtonTextBeforeAutoClose = okButton.Text;
autoCloseSecondsRemaining = Math.Max(1, (int)Math.Ceiling(delayMs / 1000D));
UpdateAutoCloseButtonText();
autoCloseTimer = new System.Windows.Forms.Timer { Interval = 1000 };
autoCloseTimer.Tick += AutoCloseTimer_Tick;
autoCloseTimer.Start();
}
private async Task AutoClickInternal(Button clickButton, int delayMs)
private void AutoCloseTimer_Tick(object sender, EventArgs e)
{
await Task.Delay(delayMs);
if (clickButton.IsHandleCreated && clickButton.Enabled && clickButton.Visible)
autoCloseSecondsRemaining--;
if (autoCloseSecondsRemaining > 0)
{
// Invoke on UI thread
if (clickButton.InvokeRequired)
clickButton.BeginInvoke(new Action(() => clickButton.PerformClick()));
else
clickButton.PerformClick();
UpdateAutoCloseButtonText();
return;
}
bool canClick = okButton.IsHandleCreated && okButton.Enabled && okButton.Visible;
StopAutoCloseCountdown();
if (canClick)
okButton.PerformClick();
}
private void UpdateAutoCloseButtonText()
{
okButton.Text = string.Format("{0} ({1})", okButtonTextBeforeAutoClose, autoCloseSecondsRemaining);
}
private void StopAutoCloseCountdown()
{
if (autoCloseTimer != null)
{
autoCloseTimer.Stop();
autoCloseTimer.Tick -= AutoCloseTimer_Tick;
autoCloseTimer.Dispose();
autoCloseTimer = null;
}
if (okButtonTextBeforeAutoClose != null && !okButton.IsDisposed)
okButton.Text = okButtonTextBeforeAutoClose;
okButtonTextBeforeAutoClose = null;
autoCloseSecondsRemaining = 0;
}
}
}

View File

@ -346,7 +346,7 @@ namespace TBF.Rig.DataEntry.Uni
BgIsCameraPicture = false;
BgFormCloseKeys = string.Empty;
BgIsAutoReadingSerialNo = false;
BgAutoCloseGap = 10;
BgAutoCloseGap = 5;
EnShowForm = false;
EnTitle = "Enter water meter data";

View File

@ -126,6 +126,9 @@ namespace TBF.Rig.DataEntry.Uni
/// Set to 'true' when the form closes
public bool Completed { get { return completed; } }
bool completed;
private System.Windows.Forms.Timer autoCloseTimer;
private int autoCloseSecondsRemaining;
private string okButtonTextBeforeAutoClose;
/// <summary>
@ -678,7 +681,7 @@ namespace TBF.Rig.DataEntry.Uni
if (iAutocloseGap > 0)
{
AutoClickOkAfterDelay();
AutoClickOkAfterDelay(iAutocloseGap * 1000);
}
}
@ -1108,6 +1111,7 @@ namespace TBF.Rig.DataEntry.Uni
private void okButton_Click(object sender, EventArgs eArgs)
{
StopAutoCloseCountdown();
UpdateWMsFromBoxes();
completed = true;
@ -1548,6 +1552,7 @@ namespace TBF.Rig.DataEntry.Uni
void OnForceClose(object sender, EventArgs args)
{
StopAutoCloseCountdown();
DialogResult = DialogResult.Cancel;
Close();
}
@ -1680,23 +1685,62 @@ namespace TBF.Rig.DataEntry.Uni
log.Debug("Reading Start Volume DONE!");
}
public void AutoClickOkAfterDelay(int delayMs = 10000)
public void AutoClickOkAfterDelay(int delayMs = 5000)
{
_ = AutoClickInternal(okButton, delayMs);
if (delayMs <= 0 || IsDisposed || Disposing)
return;
if (InvokeRequired)
{
BeginInvoke(new Action<int>(AutoClickOkAfterDelay), delayMs);
return;
}
StopAutoCloseCountdown();
okButtonTextBeforeAutoClose = okButton.Text;
autoCloseSecondsRemaining = Math.Max(1, (int)Math.Ceiling(delayMs / 1000D));
UpdateAutoCloseButtonText();
autoCloseTimer = new System.Windows.Forms.Timer { Interval = 1000 };
autoCloseTimer.Tick += AutoCloseTimer_Tick;
autoCloseTimer.Start();
}
private async Task AutoClickInternal(Button clickButton, int delayMs)
private void AutoCloseTimer_Tick(object sender, EventArgs e)
{
await Task.Delay(delayMs);
if (clickButton.IsHandleCreated && clickButton.Enabled && clickButton.Visible)
autoCloseSecondsRemaining--;
if (autoCloseSecondsRemaining > 0)
{
// Invoke on UI thread
if (clickButton.InvokeRequired)
clickButton.BeginInvoke(new Action(() => clickButton.PerformClick()));
else
clickButton.PerformClick();
UpdateAutoCloseButtonText();
return;
}
bool canClick = okButton.IsHandleCreated && okButton.Enabled && okButton.Visible;
StopAutoCloseCountdown();
if (canClick)
okButton.PerformClick();
}
private void UpdateAutoCloseButtonText()
{
okButton.Text = string.Format("{0} ({1})", okButtonTextBeforeAutoClose, autoCloseSecondsRemaining);
}
private void StopAutoCloseCountdown()
{
if (autoCloseTimer != null)
{
autoCloseTimer.Stop();
autoCloseTimer.Tick -= AutoCloseTimer_Tick;
autoCloseTimer.Dispose();
autoCloseTimer = null;
}
if (okButtonTextBeforeAutoClose != null && !okButton.IsDisposed)
okButton.Text = okButtonTextBeforeAutoClose;
okButtonTextBeforeAutoClose = null;
autoCloseSecondsRemaining = 0;
}
}
}