MessageBox для AvaloniaUI +8


MessageBox — достаточно часто используемая форма для различных графических фреймворков, но почему-то в avalonia ей не нашлось место, тогда подарим ей жизнь самостоятельно.

Готовое решение, которому я планирую оказать поддержку и обновление, и буду рад, если кто-нибудь присоединиться, можно найти на nuget и gitlab.

Моя цель приблизиться к стандартному виндовому MsgBox по крайней мере по опыту использования.

Итак:

Вызываем

MessageBox.ShowForResult("test","Wanna test smth?");

и получаем готовое окошко с заголовком и текстовым содержимым. (Windows 10, Ubuntu 18.04)


Класс MessageBox содержит 3 метода:
ShowForResult — возвращает результат нажатия клавиш
ShowDialog — возвращает результат и делает окно MessageBox диалоговым для выбранного родительского окна
Show — отображает окно игнорируя результат нажатия клавиш

Внутри любого метода создается окно,

var messageBox = new MessageBox();

которому устанавливается контент.

 messageBox.Content = CreateBaseMsgBox(text, buttons, messageBox);

Контентом в данном случае является Grid, включающий в себя две строки: первая для текстового поля:

 var textBlock = new TextBlock();
 textBlock.Text = text;
 textBlock.TextAlignment = TextAlignment.Center;
 textBlock.TextWrapping = TextWrapping.Wrap;
 Grid.SetRow(textBlock,0);
 grid.Children.Add(textBlock);

вторая для вложенного grid с кнопками

var btnGrid = GetButtonGrid(GetButton(window, MessageBoxResult.Yes),
 GetButton(window,MessageBoxResult.No));
 Grid.SetRow(btnGrid,1);
 grid.Children.Add(btnGrid);

Полный пример метода GetButtonGrid.
private static Grid GetButtonGrid(params Button[] buttons)
        {
            var grid = new Grid();
            List<ColumnDefinition> definitions = new List<ColumnDefinition>();
            for (int i = 0; i < buttons.Length; i++)
            {
                definitions.Add(new ColumnDefinition{Width = new GridLength(5)});
                definitions.Add(new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)});
            }
            definitions.Add(new ColumnDefinition{Width = new GridLength(5)});
            grid.ColumnDefinitions.AddRange(definitions);
             var j = 1;
            foreach (var btn in buttons)
            {
                Grid.SetColumn(btn,j);
                j += 2;
                grid.Children.Add(btn);
            }
            return grid;
        }

Такой динамический подход позволяет добавлять неограниченное количество кнопок и расширять возможности MessageBox без больших изменений.

Функциональность кнопок задается методом:

GetButton(MessageBox window,MessageBoxResult result)

Подробнее
private static Button GetButton(MessageBox window,MessageBoxResult result)
        {
           var btn = new Button();
           btn.Content = result.ToString();
           btn.Click += (_, __) =>
           {
               window.Res = result;
               window.Close();
           };
           return btn;
        }


Метод принимает окно, с которым будут манипулировать кнопки, и результат, возвращаемый ими.

И, последнее, что необходимо рассмотреть — фрагмент кода, что обеспечивает результат нажатия кнопки:

var tcs = new TaskCompletionSource<MessageBoxResult>();
messageBox.Closed += delegate { tcs.TrySetResult(messageBox.Res); };
...
return tcs.Task;

В результате мы получаем различные простейшие окошки с кнопками, что позволит создавать кроссплатформенные MessageBox:




К сожалению, не доступен сервер mySQL