MessageBox — достаточно часто используемая форма для различных графических фреймворков, но почему-то в avalonia ей не нашлось место, тогда подарим ей жизнь самостоятельно.
Готовое решение, которому я планирую оказать поддержку и обновление, и буду рад, если кто-нибудь присоединиться, можно найти на nuget и gitlab.
Моя цель приблизиться к стандартному виндовому MsgBox по крайней мере по опыту использования.
Итак:
Вызываем
и получаем готовое окошко с заголовком и текстовым содержимым. (Windows 10, Ubuntu 18.04)
Класс MessageBox содержит 3 метода:
ShowForResult — возвращает результат нажатия клавиш
ShowDialog — возвращает результат и делает окно MessageBox диалоговым для выбранного родительского окна
Show — отображает окно игнорируя результат нажатия клавиш
API
Внутри любого метода создается окно,
которому устанавливается контент.
Контентом в данном случае является Grid, включающий в себя две строки: первая для текстового поля:
вторая для вложенного grid с кнопками:
Функциональность кнопок задается методом:
Метод принимает окно, с которым будут манипулировать кнопки, и результат, возвращаемый ими.
И, последнее, что необходимо рассмотреть — фрагмент кода, что обеспечивает результат нажатия кнопки:
В результате мы получаем различные простейшие окошки с кнопками, что позволит создавать кроссплатформенные MessageBox:
UPD
Добавлен метод, что пытается вызвать реализацию нативных окон, если не справляется, то вызывает окна, представленные выше.
Отдельное спасибо пользователю worldbeater.
Апи поменялось
Тут ссылка на актуальное апи.
Готовое решение, которому я планирую оказать поддержку и обновление, и буду рад, если кто-нибудь присоединиться, можно найти на 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.
Такой динамический подход позволяет добавлять неограниченное количество кнопок и расширять возможности MessageBox без больших изменений.
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.