Merge pull request #370 from irihitech/dialog-close
Dialog system improvement
This commit is contained in:
@@ -1,30 +1,27 @@
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Irihi.Avalonia.Shared.Contracts;
|
||||
using Irihi.Avalonia.Shared.Helpers;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public class CustomDialogControl: DialogControlBase
|
||||
public class CustomDialogControl : DialogControlBase
|
||||
{
|
||||
internal bool IsCloseButtonVisible { get; set; }
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
if (_closeButton is not null)
|
||||
var closeButtonVisible = IsCloseButtonVisible ??DataContext is IDialogContext;
|
||||
IsHitTestVisibleProperty.SetValue(closeButtonVisible, _closeButton);
|
||||
if (!closeButtonVisible)
|
||||
{
|
||||
_closeButton.IsVisible = IsCloseButtonVisible;
|
||||
OpacityProperty.SetValue(0, _closeButton);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
if (DataContext is IDialogContext context)
|
||||
{
|
||||
context.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnElementClosing(this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,20 +12,30 @@ namespace Ursa.Controls;
|
||||
[TemplatePart(PART_CancelButton, typeof(Button))]
|
||||
[TemplatePart(PART_YesButton, typeof(Button))]
|
||||
[TemplatePart(PART_NoButton, typeof(Button))]
|
||||
public class DefaultDialogControl: DialogControlBase
|
||||
public class DefaultDialogControl : DialogControlBase
|
||||
{
|
||||
public const string PART_OKButton = "PART_OKButton";
|
||||
public const string PART_CancelButton = "PART_CancelButton";
|
||||
public const string PART_YesButton = "PART_YesButton";
|
||||
public const string PART_NoButton = "PART_NoButton";
|
||||
|
||||
private Button? _okButton;
|
||||
|
||||
public static readonly StyledProperty<string?> TitleProperty =
|
||||
AvaloniaProperty.Register<DefaultDialogControl, string?>(
|
||||
nameof(Title));
|
||||
|
||||
public static readonly StyledProperty<DialogButton> ButtonsProperty =
|
||||
AvaloniaProperty.Register<DefaultDialogControl, DialogButton>(
|
||||
nameof(Buttons));
|
||||
|
||||
public static readonly StyledProperty<DialogMode> ModeProperty =
|
||||
AvaloniaProperty.Register<DefaultDialogControl, DialogMode>(
|
||||
nameof(Mode));
|
||||
|
||||
private Button? _cancelButton;
|
||||
private Button? _yesButton;
|
||||
private Button? _noButton;
|
||||
|
||||
public static readonly StyledProperty<string?> TitleProperty = AvaloniaProperty.Register<DefaultDialogControl, string?>(
|
||||
nameof(Title));
|
||||
|
||||
private Button? _okButton;
|
||||
private Button? _yesButton;
|
||||
|
||||
public string? Title
|
||||
{
|
||||
@@ -33,24 +43,18 @@ public class DefaultDialogControl: DialogControlBase
|
||||
set => SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<DialogButton> ButtonsProperty = AvaloniaProperty.Register<DefaultDialogControl, DialogButton>(
|
||||
nameof(Buttons));
|
||||
|
||||
public DialogButton Buttons
|
||||
{
|
||||
get => GetValue(ButtonsProperty);
|
||||
set => SetValue(ButtonsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<DialogMode> ModeProperty = AvaloniaProperty.Register<DefaultDialogControl, DialogMode>(
|
||||
nameof(Mode));
|
||||
|
||||
public DialogMode Mode
|
||||
{
|
||||
get => GetValue(ModeProperty);
|
||||
set => SetValue(ModeProperty, value);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@@ -62,56 +66,51 @@ public class DefaultDialogControl: DialogControlBase
|
||||
Button.ClickEvent.AddHandler(DefaultButtonsClose, _okButton, _cancelButton, _yesButton, _noButton);
|
||||
SetButtonVisibility();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void SetButtonVisibility()
|
||||
{
|
||||
bool isCloseButtonVisible = DataContext is IDialogContext || Buttons != DialogButton.YesNo;
|
||||
Button.IsVisibleProperty.SetValue(isCloseButtonVisible, _closeButton);
|
||||
var closeButtonVisible = IsCloseButtonVisible ?? (DataContext is IDialogContext || Buttons != DialogButton.YesNo );
|
||||
IsHitTestVisibleProperty.SetValue(closeButtonVisible, _closeButton);
|
||||
if (!closeButtonVisible)
|
||||
{
|
||||
OpacityProperty.SetValue(0, _closeButton);
|
||||
}
|
||||
switch (Buttons)
|
||||
{
|
||||
case DialogButton.None:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.OK:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton);
|
||||
IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.OKCancel:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.YesNo:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.YesNoCancel:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton);
|
||||
IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DefaultButtonsClose(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is Button button)
|
||||
{
|
||||
if (button == _okButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.OK);
|
||||
}
|
||||
else if (button == _cancelButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.Cancel);
|
||||
}
|
||||
else if (button == _yesButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.Yes);
|
||||
}
|
||||
else if (button == _noButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.No);
|
||||
}
|
||||
else if (button == _noButton) OnElementClosing(this, DialogResult.No);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +122,7 @@ public class DefaultDialogControl: DialogControlBase
|
||||
}
|
||||
else
|
||||
{
|
||||
DialogResult result = Buttons switch
|
||||
var result = Buttons switch
|
||||
{
|
||||
DialogButton.None => DialogResult.None,
|
||||
DialogButton.OK => DialogResult.OK,
|
||||
|
||||
@@ -12,22 +12,27 @@ namespace Ursa.Controls;
|
||||
[TemplatePart(PART_NoButton, typeof(Button))]
|
||||
[TemplatePart(PART_OKButton, typeof(Button))]
|
||||
[TemplatePart(PART_CancelButton, typeof(Button))]
|
||||
public class DefaultDialogWindow: DialogWindow
|
||||
public class DefaultDialogWindow : DialogWindow
|
||||
{
|
||||
protected override Type StyleKeyOverride { get; } = typeof(DefaultDialogWindow);
|
||||
|
||||
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 Button? _yesButton;
|
||||
|
||||
public static readonly StyledProperty<DialogButton> ButtonsProperty =
|
||||
AvaloniaProperty.Register<DefaultDialogWindow, DialogButton>(
|
||||
nameof(Buttons));
|
||||
|
||||
public static readonly StyledProperty<DialogMode> ModeProperty =
|
||||
AvaloniaProperty.Register<DefaultDialogWindow, DialogMode>(
|
||||
nameof(Mode));
|
||||
|
||||
private Button? _cancelButton;
|
||||
private Button? _noButton;
|
||||
private Button? _okButton;
|
||||
private Button? _cancelButton;
|
||||
|
||||
public static readonly StyledProperty<DialogButton> ButtonsProperty = AvaloniaProperty.Register<DefaultDialogWindow, DialogButton>(
|
||||
nameof(Buttons));
|
||||
private Button? _yesButton;
|
||||
protected override Type StyleKeyOverride { get; } = typeof(DefaultDialogWindow);
|
||||
|
||||
public DialogButton Buttons
|
||||
{
|
||||
@@ -35,15 +40,12 @@ public class DefaultDialogWindow: DialogWindow
|
||||
set => SetValue(ButtonsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<DialogMode> ModeProperty = AvaloniaProperty.Register<DefaultDialogWindow, DialogMode>(
|
||||
nameof(Mode));
|
||||
|
||||
public DialogMode Mode
|
||||
{
|
||||
get => GetValue(ModeProperty);
|
||||
set => SetValue(ModeProperty, value);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@@ -59,69 +61,49 @@ public class DefaultDialogWindow: DialogWindow
|
||||
private void OnDefaultClose(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Equals(sender, _yesButton))
|
||||
{
|
||||
Close(DialogResult.Yes);
|
||||
return;
|
||||
}
|
||||
if(Equals(sender, _noButton))
|
||||
{
|
||||
else if (Equals(sender, _noButton))
|
||||
Close(DialogResult.No);
|
||||
return;
|
||||
}
|
||||
if(Equals(sender, _okButton))
|
||||
{
|
||||
else if (Equals(sender, _okButton))
|
||||
Close(DialogResult.OK);
|
||||
return;
|
||||
}
|
||||
if(Equals(sender, _cancelButton))
|
||||
{
|
||||
else if (Equals(sender, _cancelButton))
|
||||
Close(DialogResult.Cancel);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetButtonVisibility()
|
||||
{
|
||||
bool closeButtonVisible = DataContext is IDialogContext || Buttons != DialogButton.YesNo;
|
||||
SetVisibility(_closeButton, closeButtonVisible);
|
||||
// Close button should be hidden instead if invisible to retain layout.
|
||||
IsVisibleProperty.SetValue(true, _closeButton);
|
||||
var closeButtonVisible =
|
||||
IsCloseButtonVisible ?? (DataContext is IDialogContext || Buttons != DialogButton.YesNo);
|
||||
IsHitTestVisibleProperty.SetValue(closeButtonVisible, _closeButton);
|
||||
if (!closeButtonVisible)
|
||||
{
|
||||
OpacityProperty.SetValue(0, _closeButton);
|
||||
}
|
||||
switch (Buttons)
|
||||
{
|
||||
case DialogButton.None:
|
||||
SetVisibility(_okButton, false);
|
||||
SetVisibility(_cancelButton, false);
|
||||
SetVisibility(_yesButton, false);
|
||||
SetVisibility(_noButton, false);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.OK:
|
||||
SetVisibility(_okButton, true);
|
||||
SetVisibility(_cancelButton, false);
|
||||
SetVisibility(_yesButton, false);
|
||||
SetVisibility(_noButton, false);
|
||||
IsVisibleProperty.SetValue(true, _okButton);
|
||||
IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.OKCancel:
|
||||
SetVisibility(_okButton, true);
|
||||
SetVisibility(_cancelButton, true);
|
||||
SetVisibility(_yesButton, false);
|
||||
SetVisibility(_noButton, false);
|
||||
IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.YesNo:
|
||||
SetVisibility(_okButton, false);
|
||||
SetVisibility(_cancelButton, false);
|
||||
SetVisibility(_yesButton, true);
|
||||
SetVisibility(_noButton, true);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.YesNoCancel:
|
||||
SetVisibility(_okButton, false);
|
||||
SetVisibility(_cancelButton, true);
|
||||
SetVisibility(_yesButton, true);
|
||||
SetVisibility(_noButton, true);
|
||||
IsVisibleProperty.SetValue(false, _okButton);
|
||||
IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetVisibility(Button? button, bool visible)
|
||||
{
|
||||
if (button is not null) button.IsVisible = visible;
|
||||
}
|
||||
|
||||
protected override void OnCloseButtonClicked(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
@@ -131,7 +113,7 @@ public class DefaultDialogWindow: DialogWindow
|
||||
}
|
||||
else
|
||||
{
|
||||
DialogResult result = Buttons switch
|
||||
var result = Buttons switch
|
||||
{
|
||||
DialogButton.None => DialogResult.None,
|
||||
DialogButton.OK => DialogResult.OK,
|
||||
|
||||
@@ -240,6 +240,7 @@ public static class Dialog
|
||||
window.Buttons = options.Button;
|
||||
window.Mode = options.Mode;
|
||||
window.ShowInTaskbar = options.ShowInTaskBar;
|
||||
window.IsCloseButtonVisible = options.IsCloseButtonVisible;
|
||||
if (options.StartupLocation == WindowStartupLocation.Manual)
|
||||
{
|
||||
if (options.Position is not null)
|
||||
|
||||
@@ -20,6 +20,22 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
public const string PC_Modal = ":modal";
|
||||
public const string PC_FullScreen = ":full-screen";
|
||||
|
||||
public static readonly DirectProperty<DialogControlBase, bool> IsFullScreenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DialogControlBase, bool>(
|
||||
nameof(IsFullScreen), o => o.IsFullScreen, (o, v) => o.IsFullScreen = v);
|
||||
|
||||
protected internal Button? _closeButton;
|
||||
|
||||
private bool _isFullScreen;
|
||||
private Panel? _titleArea;
|
||||
|
||||
static DialogControlBase()
|
||||
{
|
||||
CanDragMoveProperty.Changed.AddClassHandler<InputElement, bool>(OnCanDragMoveChanged);
|
||||
CanCloseProperty.Changed.AddClassHandler<InputElement, bool>(OnCanCloseChanged);
|
||||
IsFullScreenProperty.AffectsPseudoClass<DialogControlBase>(PC_FullScreen);
|
||||
}
|
||||
|
||||
internal HorizontalPosition HorizontalAnchor { get; set; } = HorizontalPosition.Center;
|
||||
internal VerticalPosition VerticalAnchor { get; set; } = VerticalPosition.Center;
|
||||
internal HorizontalPosition ActualHorizontalAnchor { get; set; }
|
||||
@@ -29,11 +45,7 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
internal double? HorizontalOffsetRatio { get; set; }
|
||||
internal double? VerticalOffsetRatio { get; set; }
|
||||
internal bool CanLightDismiss { get; set; }
|
||||
|
||||
private bool _isFullScreen;
|
||||
|
||||
public static readonly DirectProperty<DialogControlBase, bool> IsFullScreenProperty = AvaloniaProperty.RegisterDirect<DialogControlBase, bool>(
|
||||
nameof(IsFullScreen), o => o.IsFullScreen, (o, v) => o.IsFullScreen = v);
|
||||
internal bool? IsCloseButtonVisible { get; set; }
|
||||
|
||||
public bool IsFullScreen
|
||||
{
|
||||
@@ -41,113 +53,6 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
set => SetAndRaise(IsFullScreenProperty, ref _isFullScreen, value);
|
||||
}
|
||||
|
||||
protected internal Button? _closeButton;
|
||||
private Panel? _titleArea;
|
||||
|
||||
#region Layer Management
|
||||
|
||||
public static readonly RoutedEvent<DialogLayerChangeEventArgs> LayerChangedEvent =
|
||||
RoutedEvent.Register<CustomDialogControl, DialogLayerChangeEventArgs>(
|
||||
nameof(LayerChanged), RoutingStrategies.Bubble);
|
||||
|
||||
public event EventHandler<DialogLayerChangeEventArgs> LayerChanged
|
||||
{
|
||||
add => AddHandler(LayerChangedEvent, value);
|
||||
remove => RemoveHandler(LayerChangedEvent, value);
|
||||
}
|
||||
|
||||
public void UpdateLayer(object? o)
|
||||
{
|
||||
if (o is DialogLayerChangeType t)
|
||||
{
|
||||
RaiseEvent(new DialogLayerChangeEventArgs(LayerChangedEvent, t));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DragMove AttachedPropert
|
||||
|
||||
public static readonly AttachedProperty<bool> CanDragMoveProperty =
|
||||
AvaloniaProperty.RegisterAttached<DialogControlBase, InputElement, bool>("CanDragMove");
|
||||
|
||||
public static void SetCanDragMove(InputElement obj, bool value) => obj.SetValue(CanDragMoveProperty, value);
|
||||
public static bool GetCanDragMove(InputElement obj) => obj.GetValue(CanDragMoveProperty);
|
||||
|
||||
private static void OnCanDragMoveChanged(InputElement arg1, AvaloniaPropertyChangedEventArgs<bool> arg2)
|
||||
{
|
||||
if (arg2.NewValue.Value)
|
||||
{
|
||||
arg1.AddHandler(PointerPressedEvent, OnPointerPressed, RoutingStrategies.Bubble);
|
||||
arg1.AddHandler(PointerMovedEvent, OnPointerMoved, RoutingStrategies.Bubble);
|
||||
arg1.AddHandler(PointerReleasedEvent, OnPointerReleased, RoutingStrategies.Bubble);
|
||||
}
|
||||
else
|
||||
{
|
||||
arg1.RemoveHandler(PointerPressedEvent, OnPointerPressed);
|
||||
arg1.RemoveHandler(PointerMovedEvent, OnPointerMoved);
|
||||
arg1.RemoveHandler(PointerReleasedEvent, OnPointerReleased);
|
||||
}
|
||||
|
||||
void OnPointerPressed(InputElement sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog)
|
||||
{
|
||||
e.Source = dialog;
|
||||
}
|
||||
}
|
||||
|
||||
void OnPointerMoved(InputElement sender, PointerEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog)
|
||||
{
|
||||
e.Source = dialog;
|
||||
}
|
||||
}
|
||||
|
||||
void OnPointerReleased(InputElement sender, PointerReleasedEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog)
|
||||
{
|
||||
e.Source = dialog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Close AttachedProperty
|
||||
|
||||
public static readonly AttachedProperty<bool> CanCloseProperty =
|
||||
AvaloniaProperty.RegisterAttached<DialogControlBase, InputElement, bool>("CanClose");
|
||||
|
||||
public static void SetCanClose(InputElement obj, bool value) => obj.SetValue(CanCloseProperty, value);
|
||||
public static bool GetCanClose(InputElement obj) => obj.GetValue(CanCloseProperty);
|
||||
private static void OnCanCloseChanged(InputElement arg1, AvaloniaPropertyChangedEventArgs<bool> arg2)
|
||||
{
|
||||
if (arg2.NewValue.Value)
|
||||
{
|
||||
arg1.AddHandler(PointerPressedEvent, OnPointerPressed, RoutingStrategies.Bubble);
|
||||
}
|
||||
void OnPointerPressed(InputElement sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog)
|
||||
{
|
||||
dialog.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
static DialogControlBase()
|
||||
{
|
||||
CanDragMoveProperty.Changed.AddClassHandler<InputElement, bool>(OnCanDragMoveChanged);
|
||||
CanCloseProperty.Changed.AddClassHandler<InputElement, bool>(OnCanCloseChanged);
|
||||
IsFullScreenProperty.AffectsPseudoClass<DialogControlBase>(PC_FullScreen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
@@ -188,10 +93,107 @@ public abstract class DialogControlBase : OverlayFeedbackElement
|
||||
e.Source = this;
|
||||
}
|
||||
|
||||
private void OnCloseButtonClick(object? sender, RoutedEventArgs args) => Close();
|
||||
private void OnCloseButtonClick(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
internal void SetAsModal(bool modal)
|
||||
{
|
||||
PseudoClasses.Set(PC_Modal, modal);
|
||||
}
|
||||
|
||||
#region Layer Management
|
||||
|
||||
public static readonly RoutedEvent<DialogLayerChangeEventArgs> LayerChangedEvent =
|
||||
RoutedEvent.Register<CustomDialogControl, DialogLayerChangeEventArgs>(
|
||||
nameof(LayerChanged), RoutingStrategies.Bubble);
|
||||
|
||||
public event EventHandler<DialogLayerChangeEventArgs> LayerChanged
|
||||
{
|
||||
add => AddHandler(LayerChangedEvent, value);
|
||||
remove => RemoveHandler(LayerChangedEvent, value);
|
||||
}
|
||||
|
||||
public void UpdateLayer(object? o)
|
||||
{
|
||||
if (o is DialogLayerChangeType t) RaiseEvent(new DialogLayerChangeEventArgs(LayerChangedEvent, t));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DragMove AttachedPropert
|
||||
|
||||
public static readonly AttachedProperty<bool> CanDragMoveProperty =
|
||||
AvaloniaProperty.RegisterAttached<DialogControlBase, InputElement, bool>("CanDragMove");
|
||||
|
||||
public static void SetCanDragMove(InputElement obj, bool value)
|
||||
{
|
||||
obj.SetValue(CanDragMoveProperty, value);
|
||||
}
|
||||
|
||||
public static bool GetCanDragMove(InputElement obj)
|
||||
{
|
||||
return obj.GetValue(CanDragMoveProperty);
|
||||
}
|
||||
|
||||
private static void OnCanDragMoveChanged(InputElement arg1, AvaloniaPropertyChangedEventArgs<bool> arg2)
|
||||
{
|
||||
if (arg2.NewValue.Value)
|
||||
{
|
||||
arg1.AddHandler(PointerPressedEvent, OnPointerPressed, RoutingStrategies.Bubble);
|
||||
arg1.AddHandler(PointerMovedEvent, OnPointerMoved, RoutingStrategies.Bubble);
|
||||
arg1.AddHandler(PointerReleasedEvent, OnPointerReleased, RoutingStrategies.Bubble);
|
||||
}
|
||||
else
|
||||
{
|
||||
arg1.RemoveHandler(PointerPressedEvent, OnPointerPressed);
|
||||
arg1.RemoveHandler(PointerMovedEvent, OnPointerMoved);
|
||||
arg1.RemoveHandler(PointerReleasedEvent, OnPointerReleased);
|
||||
}
|
||||
|
||||
void OnPointerPressed(InputElement sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog) e.Source = dialog;
|
||||
}
|
||||
|
||||
void OnPointerMoved(InputElement sender, PointerEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog) e.Source = dialog;
|
||||
}
|
||||
|
||||
void OnPointerReleased(InputElement sender, PointerReleasedEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog) e.Source = dialog;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Close AttachedProperty
|
||||
|
||||
public static readonly AttachedProperty<bool> CanCloseProperty =
|
||||
AvaloniaProperty.RegisterAttached<DialogControlBase, InputElement, bool>("CanClose");
|
||||
|
||||
public static void SetCanClose(InputElement obj, bool value)
|
||||
{
|
||||
obj.SetValue(CanCloseProperty, value);
|
||||
}
|
||||
|
||||
public static bool GetCanClose(InputElement obj)
|
||||
{
|
||||
return obj.GetValue(CanCloseProperty);
|
||||
}
|
||||
|
||||
private static void OnCanCloseChanged(InputElement arg1, AvaloniaPropertyChangedEventArgs<bool> arg2)
|
||||
{
|
||||
if (arg2.NewValue.Value) arg1.AddHandler(PointerPressedEvent, OnPointerPressed, RoutingStrategies.Bubble);
|
||||
|
||||
void OnPointerPressed(InputElement sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender.FindLogicalAncestorOfType<DialogControlBase>() is { } dialog) dialog.Close();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -11,33 +11,29 @@ namespace Ursa.Controls;
|
||||
|
||||
[TemplatePart(PART_CloseButton, typeof(Button))]
|
||||
[TemplatePart(PART_TitleArea, typeof(Panel))]
|
||||
public class DialogWindow: Window
|
||||
public class DialogWindow : Window
|
||||
{
|
||||
public const string PART_CloseButton = "PART_CloseButton";
|
||||
public const string PART_TitleArea = "PART_TitleArea";
|
||||
protected override Type StyleKeyOverride { get; } = typeof(DialogWindow);
|
||||
|
||||
protected internal Button? _closeButton;
|
||||
private Panel? _titleArea;
|
||||
|
||||
internal bool IsCloseButtonVisible { get; set; }
|
||||
|
||||
static DialogWindow()
|
||||
{
|
||||
DataContextProperty.Changed.AddClassHandler<DialogWindow, object?>((o, e) => o.OnDataContextChange(e));
|
||||
DataContextProperty.Changed.AddClassHandler<DialogWindow, object?>((window, e) =>
|
||||
window.OnDataContextChange(e));
|
||||
}
|
||||
|
||||
|
||||
protected override Type StyleKeyOverride { get; } = typeof(DialogWindow);
|
||||
|
||||
internal bool? IsCloseButtonVisible { get; set; }
|
||||
|
||||
private void OnDataContextChange(AvaloniaPropertyChangedEventArgs<object?> args)
|
||||
{
|
||||
if (args.OldValue.Value is IDialogContext oldContext)
|
||||
{
|
||||
oldContext.RequestClose-= OnContextRequestClose;
|
||||
}
|
||||
if (args.OldValue.Value is IDialogContext oldContext) oldContext.RequestClose -= OnContextRequestClose;
|
||||
|
||||
if (args.NewValue.Value is IDialogContext newContext)
|
||||
{
|
||||
newContext.RequestClose += OnContextRequestClose;
|
||||
}
|
||||
if (args.NewValue.Value is IDialogContext newContext) newContext.RequestClose += OnContextRequestClose;
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
@@ -46,11 +42,10 @@ public class DialogWindow: Window
|
||||
Button.ClickEvent.RemoveHandler(OnCloseButtonClicked, _closeButton);
|
||||
_titleArea?.RemoveHandler(PointerPressedEvent, OnTitlePointerPressed);
|
||||
_closeButton = e.NameScope.Find<Button>(PART_CloseButton);
|
||||
Button.IsVisibleProperty.SetValue(IsCloseButtonVisible, _closeButton);
|
||||
IsVisibleProperty.SetValue(IsCloseButtonVisible ?? true, _closeButton);
|
||||
Button.ClickEvent.AddHandler(OnCloseButtonClicked, _closeButton);
|
||||
_titleArea = e.NameScope.Find<Panel>(PART_TitleArea);
|
||||
_titleArea?.AddHandler(PointerPressedEvent, OnTitlePointerPressed, RoutingStrategies.Bubble);
|
||||
|
||||
}
|
||||
|
||||
private void OnContextRequestClose(object? sender, object? args)
|
||||
@@ -61,17 +56,13 @@ public class DialogWindow: Window
|
||||
protected virtual void OnCloseButtonClicked(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
if (DataContext is IDialogContext context)
|
||||
{
|
||||
context.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Close(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnTitlePointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
this.BeginMoveDrag(e);
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public class DialogOptions
|
||||
|
||||
public DialogButton Button { get; set; } = DialogButton.OKCancel;
|
||||
|
||||
public bool IsCloseButtonVisible { get; set; } = true;
|
||||
public bool? IsCloseButtonVisible { get; set; } = true;
|
||||
|
||||
public bool ShowInTaskBar { get; set; } = true;
|
||||
}
|
||||
@@ -16,40 +16,50 @@ public enum VerticalPosition
|
||||
|
||||
public class OverlayDialogOptions
|
||||
{
|
||||
internal static OverlayDialogOptions Default { get; } = new OverlayDialogOptions();
|
||||
internal static OverlayDialogOptions Default { get; } = new();
|
||||
public bool FullScreen { get; set; }
|
||||
public HorizontalPosition HorizontalAnchor { get; set; } = HorizontalPosition.Center;
|
||||
public VerticalPosition VerticalAnchor { get; set; } = VerticalPosition.Center;
|
||||
|
||||
/// <summary>
|
||||
/// This attribute is only used when HorizontalAnchor is not Center
|
||||
/// This attribute is only used when HorizontalAnchor is not Center
|
||||
/// </summary>
|
||||
public double? HorizontalOffset { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// This attribute is only used when VerticalAnchor is not Center
|
||||
/// This attribute is only used when VerticalAnchor is not Center
|
||||
/// </summary>
|
||||
public double? VerticalOffset { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Only works for DefaultDialogControl
|
||||
/// Only works for DefaultDialogControl
|
||||
/// </summary>
|
||||
public DialogMode Mode { get; set; } = DialogMode.None;
|
||||
|
||||
/// <summary>
|
||||
/// Only works for DefaultDialogControl
|
||||
/// Only works for DefaultDialogControl
|
||||
/// </summary>
|
||||
public DialogButton Buttons { get; set; } = DialogButton.OKCancel;
|
||||
|
||||
/// <summary>
|
||||
/// Only works for DefaultDialogControl
|
||||
/// Only works for DefaultDialogControl
|
||||
/// </summary>
|
||||
public string? Title { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Only works for CustomDialogControl
|
||||
/// Only works for CustomDialogControl
|
||||
/// </summary>
|
||||
public bool IsCloseButtonVisible { get; set; } = true;
|
||||
[Obsolete()]
|
||||
public bool ShowCloseButton { get; set; } = true;
|
||||
public bool? IsCloseButtonVisible { get; set; } = true;
|
||||
|
||||
[Obsolete] public bool ShowCloseButton { get; set; } = true;
|
||||
|
||||
public bool CanLightDismiss { get; set; }
|
||||
public bool CanDragMove { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// The hash code of the top level dialog host. This is used to identify the dialog host if there are multiple dialog hosts with the same id. If this is not provided, the dialog will be added to the first dialog host with the same id.
|
||||
/// The hash code of the top level dialog host. This is used to identify the dialog host if there are multiple dialog
|
||||
/// hosts with the same id. If this is not provided, the dialog will be added to the first dialog host with the same
|
||||
/// id.
|
||||
/// </summary>
|
||||
public int? TopLevelHashCode { get; set; }
|
||||
}
|
||||
@@ -221,6 +221,7 @@ public static class OverlayDialog
|
||||
control.Buttons = options.Buttons;
|
||||
control.Title = options.Title;
|
||||
control.CanLightDismiss = options.CanLightDismiss;
|
||||
control.IsCloseButtonVisible = options.IsCloseButtonVisible;
|
||||
DialogControlBase.SetCanDragMove(control, options.CanDragMove);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class CustomDrawerControl: DrawerControlBase
|
||||
base.OnApplyTemplate(e);
|
||||
if (_closeButton is not null)
|
||||
{
|
||||
_closeButton.IsVisible = IsCloseButtonVisible;
|
||||
_closeButton.IsVisible = IsCloseButtonVisible ?? true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,20 +13,30 @@ namespace Ursa.Controls;
|
||||
[TemplatePart(PART_NoButton, typeof(Button))]
|
||||
[TemplatePart(PART_OKButton, typeof(Button))]
|
||||
[TemplatePart(PART_CancelButton, typeof(Button))]
|
||||
public class DefaultDrawerControl: DrawerControlBase
|
||||
public class DefaultDrawerControl : DrawerControlBase
|
||||
{
|
||||
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 Button? _yesButton;
|
||||
|
||||
public static readonly StyledProperty<DialogButton> ButtonsProperty =
|
||||
AvaloniaProperty.Register<DefaultDrawerControl, DialogButton>(
|
||||
nameof(Buttons), DialogButton.OKCancel);
|
||||
|
||||
public static readonly StyledProperty<DialogMode> ModeProperty =
|
||||
AvaloniaProperty.Register<DefaultDrawerControl, DialogMode>(
|
||||
nameof(Mode), DialogMode.None);
|
||||
|
||||
public static readonly StyledProperty<string?> TitleProperty =
|
||||
AvaloniaProperty.Register<DefaultDrawerControl, string?>(
|
||||
nameof(Title));
|
||||
|
||||
private Button? _cancelButton;
|
||||
private Button? _noButton;
|
||||
private Button? _okButton;
|
||||
private Button? _cancelButton;
|
||||
|
||||
public static readonly StyledProperty<DialogButton> ButtonsProperty = AvaloniaProperty.Register<DefaultDrawerControl, DialogButton>(
|
||||
nameof(Buttons), DialogButton.OKCancel);
|
||||
private Button? _yesButton;
|
||||
|
||||
public DialogButton Buttons
|
||||
{
|
||||
@@ -34,24 +44,18 @@ public class DefaultDrawerControl: DrawerControlBase
|
||||
set => SetValue(ButtonsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<DialogMode> ModeProperty = AvaloniaProperty.Register<DefaultDrawerControl, DialogMode>(
|
||||
nameof(Mode), DialogMode.None);
|
||||
|
||||
public DialogMode Mode
|
||||
{
|
||||
get => GetValue(ModeProperty);
|
||||
set => SetValue(ModeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<string?> TitleProperty = AvaloniaProperty.Register<DefaultDrawerControl, string?>(
|
||||
nameof(Title));
|
||||
|
||||
public string? Title
|
||||
{
|
||||
get => GetValue(TitleProperty);
|
||||
set => SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@@ -63,58 +67,54 @@ public class DefaultDrawerControl: DrawerControlBase
|
||||
Button.ClickEvent.AddHandler(OnDefaultButtonClick, _yesButton, _noButton, _okButton, _cancelButton);
|
||||
SetButtonVisibility();
|
||||
}
|
||||
|
||||
|
||||
private void SetButtonVisibility()
|
||||
{
|
||||
bool isCloseButtonVisible = DataContext is IDialogContext || Buttons != DialogButton.YesNo;
|
||||
Button.IsVisibleProperty.SetValue(isCloseButtonVisible, _closeButton);
|
||||
var closeButtonVisible =
|
||||
IsCloseButtonVisible ?? (DataContext is IDialogContext || Buttons != DialogButton.YesNo);
|
||||
IsHitTestVisibleProperty.SetValue(closeButtonVisible, _closeButton);
|
||||
if (!closeButtonVisible)
|
||||
{
|
||||
OpacityProperty.SetValue(0, _closeButton);
|
||||
}
|
||||
switch (Buttons)
|
||||
{
|
||||
case DialogButton.None:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.OK:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton);
|
||||
IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.OKCancel:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.YesNo:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
break;
|
||||
case DialogButton.YesNoCancel:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton);
|
||||
IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnDefaultButtonClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button)
|
||||
{
|
||||
if (button == _okButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.OK);
|
||||
}
|
||||
else if (button == _cancelButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.Cancel);
|
||||
}
|
||||
else if (button == _yesButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.Yes);
|
||||
}
|
||||
else if (button == _noButton)
|
||||
{
|
||||
OnElementClosing(this, DialogResult.No);
|
||||
}
|
||||
else if (button == _noButton) OnElementClosing(this, DialogResult.No);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
if (DataContext is IDialogContext context)
|
||||
@@ -123,7 +123,7 @@ public class DefaultDrawerControl: DrawerControlBase
|
||||
}
|
||||
else
|
||||
{
|
||||
DialogResult result = Buttons switch
|
||||
var result = Buttons switch
|
||||
{
|
||||
DialogButton.None => DialogResult.None,
|
||||
DialogButton.OK => DialogResult.OK,
|
||||
|
||||
@@ -37,15 +37,7 @@ public abstract class DrawerControlBase: OverlayFeedbackElement
|
||||
set => SetValue(IsOpenProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IsCloseButtonVisibleProperty =
|
||||
AvaloniaProperty.Register<DrawerControlBase, bool>(
|
||||
nameof(IsCloseButtonVisible), defaultValue: true);
|
||||
|
||||
public bool IsCloseButtonVisible
|
||||
{
|
||||
get => GetValue(IsCloseButtonVisibleProperty);
|
||||
set => SetValue(IsCloseButtonVisibleProperty, value);
|
||||
}
|
||||
internal bool? IsCloseButtonVisible { get; set; }
|
||||
|
||||
protected internal bool CanLightDismiss { get; set; }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ public class DrawerOptions
|
||||
internal static DrawerOptions Default => new ();
|
||||
public Position Position { get; set; } = Position.Right;
|
||||
public bool CanLightDismiss { get; set; } = true;
|
||||
public bool IsCloseButtonVisible { get; set; } = true;
|
||||
public bool? IsCloseButtonVisible { get; set; } = true;
|
||||
public double? MinWidth { get; set; } = null;
|
||||
public double? MinHeight { get; set; } = null;
|
||||
public double? MaxWidth { get; set; } = null;
|
||||
|
||||
@@ -8,57 +8,60 @@ using Irihi.Avalonia.Shared.Helpers;
|
||||
namespace Ursa.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// The messageBox used to display in OverlayDialogHost.
|
||||
/// The messageBox used to display in OverlayDialogHost.
|
||||
/// </summary>
|
||||
[TemplatePart(PART_NoButton, typeof(Button))]
|
||||
[TemplatePart(PART_OKButton, typeof(Button))]
|
||||
[TemplatePart(PART_CancelButton, typeof(Button))]
|
||||
[TemplatePart(PART_YesButton, typeof(Button))]
|
||||
public class MessageBoxControl: DialogControlBase
|
||||
public class MessageBoxControl : DialogControlBase
|
||||
{
|
||||
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 Button? _yesButton;
|
||||
private Button? _noButton;
|
||||
private Button? _okButton;
|
||||
private Button? _cancelButton;
|
||||
|
||||
|
||||
public static readonly StyledProperty<MessageBoxIcon> MessageIconProperty =
|
||||
AvaloniaProperty.Register<MessageBoxWindow, MessageBoxIcon>(
|
||||
nameof(MessageIcon));
|
||||
|
||||
public static readonly StyledProperty<MessageBoxButton> ButtonsProperty =
|
||||
AvaloniaProperty.Register<MessageBoxControl, MessageBoxButton>(
|
||||
nameof(Buttons));
|
||||
|
||||
public static readonly StyledProperty<string?> TitleProperty =
|
||||
AvaloniaProperty.Register<MessageBoxControl, string?>(
|
||||
nameof(Title));
|
||||
|
||||
private Button? _cancelButton;
|
||||
private Button? _noButton;
|
||||
private Button? _okButton;
|
||||
|
||||
private Button? _yesButton;
|
||||
|
||||
static MessageBoxControl()
|
||||
{
|
||||
ButtonsProperty.Changed.AddClassHandler<MessageBoxControl>((o, _) => { o.SetButtonVisibility(); });
|
||||
}
|
||||
|
||||
public MessageBoxIcon MessageIcon
|
||||
{
|
||||
get => GetValue(MessageIconProperty);
|
||||
set => SetValue(MessageIconProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<MessageBoxButton> ButtonsProperty = AvaloniaProperty.Register<MessageBoxControl, MessageBoxButton>(
|
||||
nameof(Buttons));
|
||||
|
||||
public MessageBoxButton Buttons
|
||||
{
|
||||
get => GetValue(ButtonsProperty);
|
||||
set => SetValue(ButtonsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<string?> TitleProperty = AvaloniaProperty.Register<MessageBoxControl, string?>(
|
||||
nameof(Title));
|
||||
|
||||
public string? Title
|
||||
{
|
||||
get => GetValue(TitleProperty);
|
||||
set => SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
static MessageBoxControl()
|
||||
{
|
||||
ButtonsProperty.Changed.AddClassHandler<MessageBoxControl>((o, _) => { o.SetButtonVisibility(); });
|
||||
}
|
||||
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@@ -71,55 +74,66 @@ public class MessageBoxControl: DialogControlBase
|
||||
SetButtonVisibility();
|
||||
}
|
||||
|
||||
protected override void OnLoaded(RoutedEventArgs e)
|
||||
{
|
||||
base.OnLoaded(e);
|
||||
var defaultButton = Buttons switch
|
||||
{
|
||||
MessageBoxButton.OK => _okButton,
|
||||
MessageBoxButton.OKCancel => _cancelButton,
|
||||
MessageBoxButton.YesNo => _yesButton,
|
||||
MessageBoxButton.YesNoCancel => _cancelButton,
|
||||
_ => null
|
||||
};
|
||||
defaultButton?.Focus();
|
||||
}
|
||||
|
||||
private void DefaultButtonsClose(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button)
|
||||
if (sender is not Button button) return;
|
||||
var result = button switch
|
||||
{
|
||||
if (button == _okButton)
|
||||
{
|
||||
OnElementClosing(this, MessageBoxResult.OK);
|
||||
}
|
||||
else if (button == _cancelButton)
|
||||
{
|
||||
OnElementClosing(this, MessageBoxResult.Cancel);
|
||||
}
|
||||
else if (button == _yesButton)
|
||||
{
|
||||
OnElementClosing(this, MessageBoxResult.Yes);
|
||||
}
|
||||
else if (button == _noButton)
|
||||
{
|
||||
OnElementClosing(this, MessageBoxResult.No);
|
||||
}
|
||||
}
|
||||
_ when button == _okButton => MessageBoxResult.OK,
|
||||
_ when button == _cancelButton => MessageBoxResult.Cancel,
|
||||
_ when button == _yesButton => MessageBoxResult.Yes,
|
||||
_ when button == _noButton => MessageBoxResult.No,
|
||||
_ => MessageBoxResult.None
|
||||
};
|
||||
OnElementClosing(this, result);
|
||||
}
|
||||
|
||||
|
||||
private void SetButtonVisibility()
|
||||
{
|
||||
var closeButtonVisible = Buttons != MessageBoxButton.YesNo;
|
||||
IsVisibleProperty.SetValue(closeButtonVisible, _closeButton);
|
||||
switch (Buttons)
|
||||
{
|
||||
case MessageBoxButton.OK:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton);
|
||||
IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
Button.IsDefaultProperty.SetValue(true, _okButton);
|
||||
Button.IsDefaultProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case MessageBoxButton.OKCancel:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
Button.IsDefaultProperty.SetValue(true, _okButton);
|
||||
Button.IsDefaultProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case MessageBoxButton.YesNo:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton);
|
||||
IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
MessageBoxResult result = Buttons switch
|
||||
var result = Buttons switch
|
||||
{
|
||||
MessageBoxButton.OK => MessageBoxResult.OK,
|
||||
MessageBoxButton.OKCancel => MessageBoxResult.Cancel,
|
||||
|
||||
@@ -21,28 +21,29 @@ public class MessageBoxWindow(MessageBoxButton buttons) : Window
|
||||
public const string PART_OKButton = "PART_OKButton";
|
||||
public const string PART_CancelButton = "PART_CancelButton";
|
||||
|
||||
private Button? _closeButton;
|
||||
private Button? _yesButton;
|
||||
private Button? _noButton;
|
||||
private Button? _okButton;
|
||||
private Button? _cancelButton;
|
||||
|
||||
protected override Type StyleKeyOverride => typeof(MessageBoxWindow);
|
||||
|
||||
public static readonly StyledProperty<MessageBoxIcon> MessageIconProperty =
|
||||
AvaloniaProperty.Register<MessageBoxWindow, MessageBoxIcon>(
|
||||
nameof(MessageIcon));
|
||||
|
||||
private Button? _closeButton;
|
||||
|
||||
private Button? _cancelButton;
|
||||
private Button? _noButton;
|
||||
private Button? _okButton;
|
||||
private Button? _yesButton;
|
||||
|
||||
public MessageBoxWindow() : this(MessageBoxButton.OK)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Type StyleKeyOverride => typeof(MessageBoxWindow);
|
||||
|
||||
public MessageBoxIcon MessageIcon
|
||||
{
|
||||
get => GetValue(MessageIconProperty);
|
||||
set => SetValue(MessageIconProperty, value);
|
||||
}
|
||||
|
||||
public MessageBoxWindow() : this(MessageBoxButton.OK)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@@ -60,33 +61,32 @@ public class MessageBoxWindow(MessageBoxButton buttons) : Window
|
||||
|
||||
private void SetButtonVisibility()
|
||||
{
|
||||
var closeButtonVisible = buttons != MessageBoxButton.YesNo;
|
||||
IsVisibleProperty.SetValue(closeButtonVisible, _closeButton);
|
||||
switch (buttons)
|
||||
{
|
||||
case MessageBoxButton.OK:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton);
|
||||
IsVisibleProperty.SetValue(false, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
case MessageBoxButton.OKCancel:
|
||||
Button.IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(true, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(false, _yesButton, _noButton);
|
||||
break;
|
||||
case MessageBoxButton.YesNo:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton, _cancelButton);
|
||||
IsVisibleProperty.SetValue(true, _yesButton, _noButton);
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
Button.IsVisibleProperty.SetValue(false, _okButton);
|
||||
Button.IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
IsVisibleProperty.SetValue(false, _okButton);
|
||||
IsVisibleProperty.SetValue(true, _cancelButton, _yesButton, _noButton);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCloseButtonClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (buttons == MessageBoxButton.OK)
|
||||
{
|
||||
Close(MessageBoxResult.OK);
|
||||
}
|
||||
if (buttons == MessageBoxButton.OK) Close(MessageBoxResult.OK);
|
||||
|
||||
Close(MessageBoxResult.Cancel);
|
||||
}
|
||||
@@ -94,29 +94,29 @@ public class MessageBoxWindow(MessageBoxButton buttons) : Window
|
||||
private void OnDefaultButtonClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Equals(sender, _okButton))
|
||||
{
|
||||
Close(MessageBoxResult.OK);
|
||||
}
|
||||
else if (Equals(sender, _cancelButton))
|
||||
{
|
||||
Close(MessageBoxResult.Cancel);
|
||||
}
|
||||
else if (Equals(sender, _yesButton))
|
||||
{
|
||||
Close(MessageBoxResult.Yes);
|
||||
}
|
||||
else if (Equals(sender, _noButton))
|
||||
{
|
||||
Close(MessageBoxResult.No);
|
||||
}
|
||||
else if (Equals(sender, _noButton)) Close(MessageBoxResult.No);
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyUp(e);
|
||||
if (e.Key == Key.Escape && buttons == MessageBoxButton.OK)
|
||||
if (e.Key != Key.Escape) return;
|
||||
switch (buttons)
|
||||
{
|
||||
Close(MessageBoxResult.OK);
|
||||
case MessageBoxButton.OK:
|
||||
Close(MessageBoxResult.OK);
|
||||
break;
|
||||
case MessageBoxButton.OKCancel:
|
||||
Close(MessageBoxResult.Cancel);
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
Close(MessageBoxResult.Cancel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,4 +124,19 @@ public class MessageBoxWindow(MessageBoxButton buttons) : Window
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
protected override void OnLoaded(RoutedEventArgs e)
|
||||
{
|
||||
base.OnLoaded(e);
|
||||
var defaultButton = buttons switch
|
||||
{
|
||||
MessageBoxButton.OK => _okButton,
|
||||
MessageBoxButton.OKCancel => _cancelButton,
|
||||
MessageBoxButton.YesNo => _yesButton,
|
||||
MessageBoxButton.YesNoCancel => _cancelButton,
|
||||
_ => null
|
||||
};
|
||||
Button.IsDefaultProperty.SetValue(true, defaultButton);
|
||||
defaultButton?.Focus();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user