In This Article

Display and Results

Once the User Prompt Content and User Prompt Buttons have been defined, it is time to show the prompt and collect feedback from the user.

Display Mode

When using the builder pattern, the following options are available for displaying a user prompt (as defined by UserPromptDisplayMode):

Value Description
Dialog On supported platforms, the prompt is hosted in a Window and shown as a dialog. Using this mode on unsupported platforms will throw PlatformNotSupportedException.
Overlay The prompt is hosted on an overlay that is displayed over the owning TopLevel (e.g., Window or browser view).
DialogPreferred Dialog will be used on supported platforms; otherwise, Overlay will be used where dialogs are not supported. (Default)

The DialogPreferred mode is the default, but the static UserPromptBuilder.DefaultDisplayMode property can be used to change the default to a different value.

The UserPromptBuilder.WithDisplayMode method can be used to configure the RequestedDisplayMode of an individual builder instance to a non-default value.

Warning

Requesting Dialog mode on unsupported platforms will throw PlatformNotSupportedException. Generally, DialogPreferred should be requested instead.

The actual display mode used may differ from the display mode requested! For example, if an existing user prompt is currently displayed as an overlay, additional user prompts will also display as an overlay even if dialogs are supported and requested. Before the prompt is shown, the ActualDisplayMode property will be set to either Dialog or Overlay based on the display mode being used.

Showing a User Prompt Dialog

The builder pattern is recommended for showing user prompts, but is not required. On supported platforms, a user prompt is typically displayed as a modal dialog. The UserPromptWindow.ShowDialog method can be used to display any UserPromptControl in a modal dialog that will automatically close and return a MessageBoxResult when the user responds.

The following code demonstrates showing a UserPromptControl as a modal dialog using UserPromptWindow and evaluating the result:

var userPromptControl = new UserPromptControl() {
	Content = "This file has been modified. Do you want to save your changes before closing?",
	StandardButtons = MessageBoxButtons.YesNo,
};
var result = await UserPromptWindow.ShowDialog(userPromptControl, "Save Changes?");
if (result == MessageBoxResult.Yes) {
	// Insert code to save changes here
}

When using the builder pattern, the Show method is used to display a prompt based on the configuration and return the result as shown in the sample blow:

var result = await UserPromptBuilder.Configure()
	.WithContent("This file has been modified. Do you want to save your changes before closing?")
	.WithStandardButtons(MessageBoxButtons.YesNo)
	.Show();
if (result == MessageBoxResult.Yes) {
	// Insert code to save changes here
}
Warning

The return value of UserPromptWindow.ShowDialog and UserPromptBuilder.Show is a Task<MessageBoxResult> that must be awaited to prevent the calling thread from proceeding before the user responds. Attempting to read the Task.Result without awaiting its completion can result in thread deadlock.

Note

See the "Configuring and Evaluating Results" section below for more details on working with the result of a prompt.

Title

All Window instances should have a title, so the UserPromptWindow.ShowDialog method optionally accepts an argument that will be used as the title of the UserPromptWindow when displayed.

When using the builder pattern, the WithTitle method is used to set the title associated with the user prompt:

await UserPromptBuilder.Configure()
	// ... other configuration options here
	.WithTitle("Actipro Avalonia Controls")
	.Show();

Overlay Title Mode

When using the builder pattern and displaying a prompt as an Overlay, the following modes are available for displaying titles (as defined by UserPromptOverlayTitleMode):

Value Description
AlwaysHide The overlay title is always hidden, even when UserPromptBuilder.Title is configured.
AlwaysShow The overlay title is always shown.
ShowWhenNoHeader An overlay title is only shown when UserPromptControl.Header is not defined since a header and title are typically redundant. (Default)

The ShowWhenNoHeader mode is the default, but the static UserPromptBuilder.DefaultOverlayTitleMode property can be used to change the default to a different value.

The UserPromptBuilder.WithOverlayTitleMode method can be used to configure the OverlayTitleMode of an individual builder instance to a non-default value.

Inferred and Fallback Titles

When a title is undefined or null, the UserPromptControl.StandardStatusIcon property is used to infer a contextually appropriate title. For example, the title is set to "Warning" when the status icon is MessageBoxImage.Warning.

If a title cannot be inferred, the static UserPromptBuilder.FallbackTitle value will be used.

If a title is still undefined, the TitleAttribute metadata of the entry assembly will be used.

Tip

See the Localization topic for details on how to customize the string resources used for inferred titles.

Close Caption Button

A UserPromptWindow will only display a Close caption button in the title bar if a response can be associated with closing the window. The CloseResult property is used to define the result associated with closing the window instead of invoking an available button. When set to MessageBoxResult.None, the Close caption button will not be displayed.

When CloseResult is set to null and the StandardButtons property is used to define the available buttons, an appropriate MessageBoxResult will be assigned to CloseResult based on the current value of StandardButtons.

For example, using MessageBoxButtons.YesNoCancel will automatically assign MessageBoxButtons.Cancel as the CloseResult. Explicitly set the CloseResult to MessageBoxResult.None to prevent the Close caption button from automatically displaying.

When using the builder pattern, the WithCloseResult method is used to set the close result:

await UserPromptBuilder.Configure()
	// ... other configuration options here
	.WithCloseResult(MessageBoxResult.Ignore)
	.Show();

Configuring and Evaluating Results

The UserPromptControl.Result property is used to read or write the user's response to a prompt and is typically only used when working with custom buttons.

The UserPromptWindow.ShowDialog method returns a Task that, once completed, will return the UserPromptControl.Result. If the UserPromptWindow is closed without invoking one of the available buttons, the value of UserPromptControl.CloseResult is used instead.

The UserPromptControl.Responding event is raised when the UserPromptControl.Result property is changed. UserPromptWindow listens to this event to know when to close the dialog.

When using the builder pattern, the Show method behaves the same as UserPromptWindow.ShowDialog.

Warning

The various Show and ShowDialog methods return a Task<MessageBoxResult> that must be awaited to prevent the calling thread from proceeding before the user responds. Attempting to read the Task.Result without awaiting its completion can result in thread deadlock.

The following example demonstrates the correct way to evaluate the result:

var result = await UserPromptBuilder.Configure()
	// ... other configuration options here
	.Show();

Default Button

Typically, the first available button will be the default button that receives initial focus. There are two ways to change this behavior to explicitly indicate which button should be the default: UserPromptControl.DefaultResult and Button.IsDefault.

When standard buttons are configured using the StandardButtons property, the default button is defined by setting the DefaultResult property to the MessageBoxResult that corresponds to the standard button.

When custom buttons are configured using the ButtonItems property, the first Button control whose IsDefault property is set to true will be configured as the default.

When using the builder pattern, the button builder's UseAsDefaultResult method is used to configure Button.IsDefault as true.

await UserPromptBuilder.Configure()
	// ... other configuration options here
	.WithButton(_ => _
		.WithResult(MessageBoxResult.Yes)
		.UseAsDefaultResult()
	)
	.Show();
Tip

Custom buttons can also use the UserPromptControl.DefaultResult property to define the default button if the desired Button has set the UserPromptControl.ButtonResult attached property to a MessageBoxResult .

Warning

The UserPromptControl.DefaultResult property is ignored if any button has set Button.IsDefault to true.

Responding Event

The UserPromptControl.Responding event is raised when the UserPromptControl.Result property is changed. UserPromptWindow listens to this event to know when to close the dialog.

When using the builder pattern, the OnResponding method is used to define a callback that will receive the UserPromptBuilder and UserPromptResponseEventArgs of the event. The following demonstrates how the callback can be used to cancel a response:

await UserPromptBuilder.Configure()
	// ... other configuration options here
	.OnResponding((builder, args) => {
		if ((builder?.Instance is UserPromptControl userPromptControl) && (userPromptControl.IsChecked)) {
			// Cancel the response
			args.Cancel = true;
		}
	})
	.Show();
Warning

The Responding event handler or OnResponding callback must be executed synchronously so the thread will be blocked waiting for the response. Otherwise, the prompt will close before the event/callback has completed executing.

Owner

When the user prompt is shown as a modal dialog, it must have an owner Window. Some of the UserPromptWindow.ShowDialog overloads allow an owner to be specified. If one is not specified, a default owner Window will be determined by the currently active Window.

When using the builder pattern, the WithOwner method is used to assign a non-default owner. Since the builder pattern supports displaying dialogs or overlays, the owner is specified as a TopLevel (which, on desktop applications, is typically a Window).

Startup Location

By default, a UserPromptWindow.WindowStartupLocation is set to CenterScreen, but this can be changed.

The UserPromptWindow.ShowDialog method accepts a callback that can be used to configure the UserPromptWindow before it is displayed. The following sample demonstrates changing the startup location to CenterOwner:

var userPromptControl = new UserPromptControl() { ... };
Window owner = null; // Use default

await UserPromptWindow.ShowDialog(
	userPromptControl,
	"Window Title",
	owner,
	window => {
		window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
	});

See the "Customize UserPromptWindow" section of the Customizing Appearance topic for more examples of how to set properties like WindowStartupLocation on the UserPromptWindow.

When using the builder pattern, the WithWindowStartupLocation method is used to specify a desired startup location.

await UserPromptBuilder.Configure()
	// ... other configuration options here
	.WithWindowStartupLocation(WindowStartupLocation.CenterOwner)
	.Show();
Tip

When using the builder pattern with auto-sizing, prompts that can be sized within the bounds of their owner Window will be configured with WindowStartupLocation.CenterOwner and only larger prompts will default to WindowStartupLocation.CenterScreen. This dynamic centering, which is the default behavior, is only available if an explicit startup location is not specified.

See the "Auto-Sizing" section below for more details.

Auto-Sizing

Auto-sizing is a feature only available when using the builder pattern. By default, this feature is only enabled when a String is used as the Content of the prompt, but the WithAutoSize method can be used to explicitly enable the functionality for non-String content as well.

Auto-sizing involves a series of calculations that attempt to generate the ideal width of the prompt. The goal is to start at a given width and then ensure the prompt does not exceed a relative height. If the prompt is too tall, the width is increased in logical steps until the height is within a desired range.

The minimum width, accessible by AutoSizeMinimumWidth, is assigned using one of the available arguments passed to the WithAutoSize method.

When UserPromptBuilder.WindowStartupLocation is null (the default), the auto-size logic will first attempt to size the prompt to a width and height that do not exceed the bounds of the owner. This is important to allow WindowStartupLocation.CenterOwner to be used without some parts of the prompt potentially displayed off screen. Otherwise, if it is not displayed as an overlay, the prompt will be sized within the working area of the screen so that WindowStartupLocation.CenterScreen can be used to fully display the prompt.

Tip

Auto-size logic is also applied to MessageBox since it uses the builder pattern to create prompts. This mean that, by default, MessageBox.Show will always attempt to center messages over the owner, but will fall back to center screen if the message is too big.