I would like to show a not interactive screen to inform the user of loading data before the actual interactive screen is shown.
Currently I am using the engine.ShowProress method before creating + showing the actual interactive dialog. Although it works fine for the purpose, it is not possible to give the loading screen a proper title. It will show the automation script name.
How can I show a default screen with a nice "loading" title without blocking any of the code ( = not waiting for any user input)
I got it to work by using this:
- Create custom dialog containing 1 Label
- Showing this dialog before running the controller
- Have the controller run the interactive dialog iso the Loading dialog.
The dialog:
public class DialogLoading : Dialog
{
public DialogLoading(IEngine engine) : base(engine)
{
Title = "Info";
LoadingText = new Label();
AddWidget(LoadingText, 0, 0);
}public Label LoadingText { get; set; }
}
Showing the loading screen:
internal void ShowLoadingScreen(string screenText)
{
var dialog = new DialogLoading(BaseEngine) { Title = "Loading" };
dialog.LoadingText.Text = screenText;
dialog.Show(false);
}
Showing an interactive screen after loading is done:
private void MyMethod()
{
userInfoMsg.AppendLine("Hang on, we are retrieving Categorization data...");
ShowLoadingScreen(userInfoMsg.ToString());
// Do other things and show progress...
// ...
ScreenController = new InteractiveController(BaseEngine);
var dialog = new DialogCategorizeTicket(BaseEngine)
{
Title = "Categorize Ticket ",
};
ScreenController.Run(dialog);
}
Hi Mieke,
I have something similar in which I grey out all the UI Fields and push updates about the progress to a TextBox.
To do this I used the "RequestManualMode" method on the InteractiveController object.
This is a small example of the code:
private readonly InteractiveController controller;
private void Confirm_Pressed(object sender, EventArgs e)
{controller.RequestManualMode(
() =>
{
StatusTextBox.IsVisible = true;
DisableAllUiFields();
ProgressUpdate($"Prepping action …");
// Do something
});
}private void ProgressUpdate(string progressString)
{
StatusTextBox.Text += $"\n[{DateTime.Now.ToLocalTime()}] {progressString}";
Show(false);Engine.GenerateInformation(progressString);
}
I think with this you should be able to create and show a proper loading screen.
Thank you, I’ll have a look.
Do note that I do not have a button that starts the logic.
The Script is triggered from a dashboard and the first thing it needs to to is collect info = the loading part.
After this I’m showing a dialog with buttons.
So I’m really looking for a means to show a screen without any buttons at all.
Hi Mieke,
We also encountered this use case.
Using the IASToolkit, you can implement it by using the following logic:
- ProgressDialog.Title = "Some Title"; // Set up title for your ProgressDialog
- ProgressDialog.Show(false); // Display ProgressDialog without user interaction
- ProgressDialog.AddProgressLine(string); // Show progress
- ProgressDialog.Finish(); // Finish showing progress
- InterActiveController.ShowDialog(ProgressDialog); // Show ProgressDialog through controller to allow user interaction.
Quick update, while testing this on DM 10.3.4, I noticed that the title was only updating after the progress was finished and I was getting a "Error trapped: Sequence contains no elements" message when running from Dashboards. As a workaround, I created a new simple Dialog that contains a single label with some text. I'm defining my custom title on this dialog and display it just before showing the initial progress.
public class Script
{
private InteractiveController app;/// <summary>
/// The Script entry point.
/// Engine.ShowUI();
/// </summary>
/// <param name="engine">Link with SLScripting process.</param>
public void Run(Engine engine)
{
try
{
engine.SetFlag(RunTimeFlags.NoKeyCaching);
engine.Timeout = TimeSpan.FromHours(10);
RunSafe(engine);
}
catch (ScriptAbortException)
{
throw;
}
catch (Exception e)
{
engine.Log("Run|Something went wrong: " + e);
ShowExceptionDialog(engine, e);
}
}private void RunSafe(Engine engine)
{
app = new InteractiveController(engine);// Define dialogs here
var emptyDialog = new EmptyDialog(engine) { Title = "My Custom Title" };
emptyDialog.Show(false);ProgressDialog progressDialog = new ProgressDialog(engine) { Title = "My custom title" };
progressDialog.OkButton.Pressed += (s, e) => engine.ExitSuccess("Done");
progressDialog.Show(false);foreach (var message in new string[] { "Doing something", "Let's wait some more", "Almost there", "Just a little push" })
{
progressDialog.AddProgressLine(message);
engine.Sleep(500);
}progressDialog.Finish();
app.Run(progressDialog);
}private void ShowExceptionDialog(Engine engine, Exception exception)
{
ExceptionDialog dialog = new ExceptionDialog(engine, exception);
dialog.OkButton.Pressed += (sender, args) => engine.ExitFail("Something went wrong during the creation of the new event.");
if (app.IsRunning) app.ShowDialog(dialog); else app.Run(dialog);
}private class EmptyDialog : Dialog
{
public EmptyDialog(IEngine engine) : base(engine)
{
AddWidget(new Label("This is a text"), 0, 0);
}
}
}
Thomas, this is not working for me.
I also noticed that your progress dialog contains a button. And what is the purpose of the emptyDialog?
I’ve used the progress dialog, no button and added 1 ProgressLine and end up with a screen that never closes and does not show any text.
Hi Mieke, the ProgressDialog (part of the toolkit) does indeed contain a button. That one is displayed after the Finish method is called and allows the user to see an overview of the steps that took place. Whenever they click the button, you could then show the next Dialog. If this is not required, I would just not call the Finish method and immediately show the next Dialog through the controller. The EmptyDialog is used as a workaround to initially set the title of the screen before showing the progress.
As of the latest publicly released NuGet versions of the toolkit, it is no longer needed to use controller.RequestManualMode to implement such functionality.
You can now execute your long-running method directly in the button event handler.