MessageBox для AvaloniaUI

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


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

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

    Итак:

    Вызываем

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

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

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

    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:



    UPD
    Добавлен метод, что пытается вызвать реализацию нативных окон, если не справляется, то вызывает окна, представленные выше.

    Отдельное спасибо пользователю worldbeater.
    Поделиться публикацией

    Похожие публикации

    Комментарии 3

      +4
      это не привычные MessageBox.
        +1
        Расположение кнопок довольно странное. Снизу они вплотную прилегают к границе родительского окна, а слева и справа есть отступы. Это выглядит неряшливо
          0
          сделан небольшой апдейт на визуал

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое