Skip to content

Instantly share code, notes, and snippets.

@mike-ward
Created February 20, 2022 14:55
Show Gist options
  • Save mike-ward/6c01662fedebb658600faecec1af3267 to your computer and use it in GitHub Desktop.
Save mike-ward/6c01662fedebb658600faecec1af3267 to your computer and use it in GitHub Desktop.
Avalonia MessageBox
<Window
x:Class="Loon.Views.Content.Controls.MessageBox"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:l="clr-namespace:Loon.Views.Content.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
MinWidth="250"
d:DesignHeight="450"
d:DesignWidth="300"
IsVisible="False"
SizeToContent="WidthAndHeight"
SystemDecorations="BorderOnly"
WindowStartupLocation="CenterOwner"
Topmost="True"
mc:Ignorable="d">
<Border
BorderThickness="2"
BorderBrush="Gray">
<StackPanel>
<TextBlock
Name="{x:Static l:MessageBox.TitleName}"
Padding="10 1 0 3"
Background="{DynamicResource ThemeControlMidBrush}"
PointerPressed="OnPointerPressed"/>
<Grid ColumnDefinitions="Auto,*"
VerticalAlignment="Center"
Margin="0 10 0 0">
<Image
Width="22"
Margin="15 0 0 0"
Source="/app.ico" />
<TextBlock
Name="{x:Static l:MessageBox.TextName}"
Margin="10"
TextWrapping="Wrap"
Grid.Column="1" />
</Grid>
<StackPanel
Name="{x:Static l:MessageBox.ButtonsName}"
Margin="10 0 10 10"
HorizontalAlignment="Right"
Orientation="Horizontal">
<StackPanel.Styles>
<Style Selector="Button">
<Setter Property="Margin" Value="10 0 0 0" />
</Style>
</StackPanel.Styles>
<!-- Buttons added in by code behind -->
</StackPanel>
</StackPanel>
</Border>
</Window>
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
namespace Loon.Views.Content.Controls
{
public class MessageBox : Window
{
// ReSharper disable ConvertToConstant.Global
public static readonly string TextName = "Text";
public static readonly string TitleName = "Title";
public static readonly string ButtonsName = "Buttons";
// ReSharper restore ConvertToConstant.Global
public enum MessageBoxButtons
{
Ok,
OkCancel,
YesNo,
YesNoCancel
}
public enum MessageBoxResult
{
Ok,
Cancel,
Yes,
No
}
// ReSharper disable once MemberCanBePrivate.Global
public MessageBox()
{
AvaloniaXamlLoader.Load(this);
}
public static async Task<MessageBoxResult> Show(string text, MessageBoxButtons buttons, PixelPoint? pixelPoint = null)
{
ContentControl? autoFocusControl = null;
var messageBoxResult = MessageBoxResult.Ok;
var msgbox = new MessageBox();
if (pixelPoint is not null)
{
msgbox.WindowStartupLocation = WindowStartupLocation.Manual;
msgbox.Position = pixelPoint.Value;
}
msgbox.FindControl<TextBlock>(TitleName).Text = App.GetString("title");
msgbox.FindControl<TextBlock>(TextName).Text = text;
var buttonPanel = msgbox.FindControl<StackPanel>(ButtonsName);
// ReSharper disable once ConvertIfStatementToSwitchStatement
if (buttons is MessageBoxButtons.Ok or MessageBoxButtons.OkCancel)
{
AddButton("OK", MessageBoxResult.Ok, isDefaultButton: true);
}
if (buttons is MessageBoxButtons.YesNo or MessageBoxButtons.YesNoCancel)
{
AddButton("Yes", MessageBoxResult.Yes);
AddButton("No", MessageBoxResult.No, isDefaultButton: true);
}
if (buttons is MessageBoxButtons.OkCancel or MessageBoxButtons.YesNoCancel)
{
AddButton("Cancel", MessageBoxResult.Cancel, isDefaultButton: true);
}
await msgbox.ShowDialog(App.MainWindow);
autoFocusControl?.Focus();
return messageBoxResult;
void AddButton(string caption, MessageBoxResult mbr, bool isDefaultButton = false)
{
var btn = new Button { Content = caption, MinWidth = 50 };
btn.Click += delegate
{
messageBoxResult = mbr;
msgbox.Close();
};
buttonPanel.Children.Add(btn);
if (isDefaultButton)
{
messageBoxResult = mbr;
autoFocusControl = btn;
}
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
e.Handled = true;
Close();
}
base.OnKeyDown(e);
}
private void OnPointerPressed(object? _, PointerPressedEventArgs e)
{
BeginMoveDrag(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment