I am programming a Windows form using C#. I have a waitform that I want to use when I am retrieving data from SQL. For example, I have a button called Refresh. When I press this button, it retrieves the data from the database again. So when I press the refresh button, the waitform opens and the data is loaded in the background. When the data loading is finished, the waitform will close.
Here is my code;
private void RefreshButton_Click(object sender, EventArgs e)
{
using (WaitForm waitForm = new WaitForm())
{
Thread thread = new Thread(() => LoadData());
thread.Start(waitForm);
waitForm.ShowDialog();
}
}
private void LoadData()
{
// Some Entitys
}
in here because of waitForm.ShowDialog()
my waitForm never close
CodePudding user response:
One of many ways to show a Winform waiting panel is to run the LoadData
method on a Task and give the WaitFormWaitingPanel
the ability to manage its own visibility.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
buttonLoadData.Click = onClickLoadData;
}
private async void onClickLoadData(object? sender, EventArgs e)
{
using (var waitForm = new WinFormWaitingPanel(this))
{
await Task.Run(() => LoadData());
}
}
private void LoadData()
{
// Mock "any" long-running synchronous task
// (SQL or otherwise)
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
Example
Semi-transparent wait form covers main form and provides wait cursor.
class WinFormWaitingPanel : Form
{
public WinFormWaitingPanel(Form owner)
{
Owner = owner;
// Size this form to cover the main form's client rectangle.
Size = Owner.ClientRectangle.Size;
FormBorderStyle = FormBorderStyle.None;
UseWaitCursor = true;
StartPosition = FormStartPosition.Manual;
Location = PointToClient(
Owner.PointToScreen(Owner.ClientRectangle.Location));
// Add a label that says "Loading..."
var label = new Label
{
Text = "Loading...",
TextAlign = ContentAlignment.MiddleCenter,
Dock = DockStyle.Fill,
};
Controls.Add(label);
// Set the form color to see-through Blue
BackColor = Color.LightBlue;
Opacity = .5;
var forceHandle = Handle;
BeginInvoke(() => ShowDialog());
}
}