feat: add default buttons.

This commit is contained in:
rabbitism
2024-01-11 02:41:58 +08:00
parent 81d54d3b28
commit 66894aa569
7 changed files with 183 additions and 30 deletions

View File

@@ -17,6 +17,6 @@ public class MessageBoxDemoViewModel: ObservableObject
private async Task OnDefaultMessageAsync() private async Task OnDefaultMessageAsync()
{ {
await MessageBox.ShowAsync("Hello Message Box"); var result = await MessageBox.ShowAsync("Hello Message Box");
} }
} }

View File

@@ -10,8 +10,6 @@
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:CompileBindings="True" x:CompileBindings="True"
ExtendClientAreaTitleBarHeightHint="48"
ExtendClientAreaToDecorationsHint="True"
x:DataType="viewModels:MainWindowViewModel" x:DataType="viewModels:MainWindowViewModel"
Icon="/Assets/Ursa.ico" Icon="/Assets/Ursa.ico"
mc:Ignorable="d"> mc:Ignorable="d">

View File

@@ -1,39 +1,52 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" <ResourceDictionary
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="https://github.com/avaloniaui"
xmlns:u="https://irihi.tech/ursa"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Add Resources Here --> xmlns:u="https://irihi.tech/ursa">
<ControlTheme TargetType="u:MessageBoxWindow" x:Key="{x:Type u:MessageBoxWindow}"> <!-- Add Resources Here -->
<ControlTheme x:Key="{x:Type u:MessageBoxWindow}" TargetType="u:MessageBoxWindow">
<Setter Property="Title" Value="{x:Null}"></Setter>
<Setter Property="Background" Value="{DynamicResource WindowDefaultBackground}" /> <Setter Property="Background" Value="{DynamicResource WindowDefaultBackground}" />
<Setter Property="TransparencyBackgroundFallback" Value="{DynamicResource WindowDefaultBackground}" /> <Setter Property="TransparencyBackgroundFallback" Value="{DynamicResource WindowDefaultBackground}" />
<Setter Property="Foreground" Value="{DynamicResource WindowDefaultForeground}" /> <Setter Property="Foreground" Value="{DynamicResource WindowDefaultForeground}" />
<Setter Property="FontSize" Value="{DynamicResource DefaultFontSize}" /> <Setter Property="FontSize" Value="{DynamicResource DefaultFontSize}" />
<Setter Property="FontFamily" Value="{DynamicResource DefaultFontFamily}" /> <Setter Property="FontFamily" Value="{DynamicResource DefaultFontFamily}" />
<Setter Property="Padding" Value="48 24"></Setter> <Setter Property="Padding" Value="48 24" />
<Setter Property="MinHeight" Value="300"></Setter> <Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="SizeToContent" Value="WidthAndHeight"></Setter> <Setter Property="WindowStartupLocation" Value="CenterOwner" />
<Setter Property="WindowStartupLocation" Value="CenterOwner"></Setter> <Setter Property="ExtendClientAreaTitleBarHeightHint" Value="0" />
<Setter Property="ExtendClientAreaTitleBarHeightHint" Value="48"></Setter> <Setter Property="ExtendClientAreaToDecorationsHint" Value="True" />
<Setter Property="ExtendClientAreaToDecorationsHint" Value="True"></Setter> <Setter Property="SystemDecorations" Value="BorderOnly" />
<Setter Property="SystemDecorations" Value="BorderOnly"></Setter> <Setter Property="CanResize" Value="True" />
<Setter Property="CanResize" Value="True"></Setter>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="u:MessageBoxWindow"> <ControlTemplate TargetType="u:MessageBoxWindow">
<Panel> <Panel>
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" /> <Border Name="PART_TransparencyFallback" IsHitTestVisible="False" />
<Border Background="{TemplateBinding Background}" IsHitTestVisible="False" /> <Border Background="{TemplateBinding Background}" IsHitTestVisible="False" />
<Panel Margin="{TemplateBinding WindowDecorationMargin}" Background="Transparent" /> <Panel Margin="{TemplateBinding WindowDecorationMargin}" Background="Transparent" />
<VisualLayerManager> <Grid RowDefinitions="Auto, *, Auto">
<VisualLayerManager.ChromeOverlayLayer> <Grid ColumnDefinitions="*, Auto" Grid.Row="0">
<TitleBar /> <TextBlock Grid.Column="0" Text="{TemplateBinding Title}" />
</VisualLayerManager.ChromeOverlayLayer> <Button
<ContentPresenter Grid.Row="0" Grid.Column="1"
Name="PART_ContentPresenter" Name="{x:Static u:MessageBoxWindow.PART_CloseButton}"
Margin="{TemplateBinding Padding}" Content="X"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" </Grid>
Content="{TemplateBinding Content}" <ContentPresenter
ContentTemplate="{TemplateBinding ContentTemplate}" /> Name="PART_ContentPresenter"
</VisualLayerManager> Grid.Row="1"
Margin="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button Name="{x:Static u:MessageBoxWindow.PART_YesButton}" Classes="Primary" Content="Yes" />
<Button Name="{x:Static u:MessageBoxWindow.PART_NoButton}" Classes="Danger" Content="No" />
<Button Name="{x:Static u:MessageBoxWindow.PART_OKButton}" Classes="Primary" Content="OK" />
<Button Name="{x:Static u:MessageBoxWindow.PART_CancelButton}" Classes="Tertiary" Content="Cancel" />
</StackPanel>
</Grid>
</Panel> </Panel>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>

View File

@@ -5,7 +5,7 @@ namespace Ursa.Controls;
public static class MessageBox public static class MessageBox
{ {
public static async Task ShowAsync(string message) public static async Task<MessageBoxResult> ShowAsync(string message)
{ {
var messageWindow = new MessageBoxWindow() var messageWindow = new MessageBoxWindow()
{ {
@@ -18,11 +18,17 @@ public static class MessageBox
if (main is null) if (main is null)
{ {
messageWindow.Show(); messageWindow.Show();
return MessageBoxResult.None;
} }
else else
{ {
await messageWindow.ShowDialog(main); var result = await messageWindow.ShowDialog<MessageBoxResult>(main);
return result;
} }
} }
else
{
return MessageBoxResult.None;
}
} }
} }

View File

@@ -0,0 +1,9 @@
namespace Ursa.Controls;
public enum MessageBoxButton
{
OK,
OKCancel,
YesNo,
YesNoCancel,
}

View File

@@ -0,0 +1,10 @@
namespace Ursa.Controls;
public enum MessageBoxResult
{
Cancel,
No,
None,
OK,
Yes,
}

View File

@@ -1,14 +1,131 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Platform; using Avalonia.Platform;
namespace Ursa.Controls; namespace Ursa.Controls;
[TemplatePart(PART_CloseButton, typeof(Button))]
[TemplatePart(PART_NoButton, typeof(Button))]
[TemplatePart(PART_OKButton, typeof(Button))]
[TemplatePart(PART_CancelButton, typeof(Button))]
[TemplatePart(PART_YesButton, typeof(Button))]
public class MessageBoxWindow: Window public class MessageBoxWindow: Window
{ {
public const string PART_CloseButton = "PART_CloseButton";
public const string PART_YesButton = "PART_YesButton";
public const string PART_NoButton = "PART_NoButton";
public const string PART_OKButton = "PART_OKButton";
public const string PART_CancelButton = "PART_CancelButton";
private MessageBoxButton _buttonConfigs;
private Button? _closeButton;
private Button? _yesButton;
private Button? _noButton;
private Button? _okButton;
private Button? _cancelButton;
protected override Type StyleKeyOverride => typeof(MessageBoxWindow); protected override Type StyleKeyOverride => typeof(MessageBoxWindow);
static MessageBoxWindow() static MessageBoxWindow()
{ {
} }
public MessageBoxWindow()
{
_buttonConfigs = MessageBoxButton.OK;
}
public MessageBoxWindow(MessageBoxButton buttons)
{
_buttonConfigs = buttons;
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
if (_closeButton != null)
{
_closeButton.Click -= OnCloseButtonClick;
}
if (_yesButton != null)
{
_yesButton.Click -= OnYesButtonClick;
}
if (_noButton != null)
{
_noButton.Click -= OnNoButtonClick;
}
if (_okButton != null)
{
_okButton.Click -= OnOKButtonClick;
}
if (_cancelButton != null)
{
_cancelButton.Click -= OnCancelButtonClick;
}
_yesButton = e.NameScope.Find<Button>(PART_YesButton);
_noButton = e.NameScope.Find<Button>(PART_NoButton);
_okButton = e.NameScope.Find<Button>(PART_OKButton);
_cancelButton = e.NameScope.Find<Button>(PART_CancelButton);
_closeButton = e.NameScope.Find<Button>(PART_CloseButton);
if (_closeButton is not null)
{
_closeButton.Click += OnCloseButtonClick;
}
if (_yesButton is not null)
{
_yesButton.Click += OnYesButtonClick;
}
if (_noButton is not null)
{
_noButton.Click += OnNoButtonClick;
}
if (_okButton is not null)
{
_okButton.Click += OnOKButtonClick;
}
if (_cancelButton is not null)
{
_cancelButton.Click += OnCancelButtonClick;
}
}
private void OnCloseButtonClick(object sender, RoutedEventArgs e)
{
this.Close(MessageBoxResult.None);
}
private void OnYesButtonClick(object sender, RoutedEventArgs e)
{
this.Close(MessageBoxResult.Yes);
}
private void OnNoButtonClick(object sender, RoutedEventArgs e)
{
this.Close(MessageBoxResult.No);
}
private void OnOKButtonClick(object sender, RoutedEventArgs e)
{
this.Close(MessageBoxResult.OK);
}
private void OnCancelButtonClick(object sender, RoutedEventArgs e)
{
this.Close(MessageBoxResult.Cancel);
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if (e.Key == Key.Escape)
{
this.Close(MessageBoxResult.None);
}
}
} }