diff --git a/samples/Avalonia.Labs.Catalog/ViewModels/ContentDialogViewModel.cs b/samples/Avalonia.Labs.Catalog/ViewModels/ContentDialogViewModel.cs new file mode 100644 index 0000000..b4a6775 --- /dev/null +++ b/samples/Avalonia.Labs.Catalog/ViewModels/ContentDialogViewModel.cs @@ -0,0 +1,156 @@ +using System.Threading.Tasks; +using System; +using Avalonia.Labs.Catalog.Views; +using Avalonia.Labs.Controls; +using ReactiveUI; + +namespace Avalonia.Labs.Catalog.ViewModels; + +internal enum DialogMode +{ + Default, + Deferal, + Input, +} + +internal class ContentDialogViewModel : ViewModelBase +{ + static ContentDialogViewModel() + { + ViewLocator.Register(typeof(ContentDialogViewModel), () => new ContentDialogView()); + } + + public ContentDialogViewModel() + { + Title = "ContentDialog"; + } + + public string? DialogTitle + { + get => _dialogTitle; + set => this.RaiseAndSetIfChanged(ref _dialogTitle, value); + } + + public string? Content + { + get => _content; + set => this.RaiseAndSetIfChanged(ref _content, value); + } + + public string PrimaryButtonText + { + get => _primaryText; + set => this.RaiseAndSetIfChanged(ref _primaryText, value); + } + + public string SecondaryButtonText + { + get => _secondaryText; + set => this.RaiseAndSetIfChanged(ref _secondaryText, value); + } + + public string CloseButtonText + { + get => _closeText; + set => this.RaiseAndSetIfChanged(ref _closeText, value); + } + + public bool FullSizeDesired + { + get => _fullSize; + set => this.RaiseAndSetIfChanged(ref _fullSize, value); + } + + public ContentDialogButton[] ContentDialogButtons { get; } = Enum.GetValues(); + + public ContentDialogButton ContentDialogDefaultButton + { + get => _defaultButton; + set => this.RaiseAndSetIfChanged(ref _defaultButton, value); + } + + public bool IsPrimaryButtonEnabled + { + get => _primaryEnabled; + set => this.RaiseAndSetIfChanged(ref _primaryEnabled, value); + } + + public bool IsSecondaryButtonEnabled + { + get => _secondaryEnabled; + set => this.RaiseAndSetIfChanged(ref _secondaryEnabled, value); + } + + + public async void LaunchDialog(object? parameter) + { + bool hasDeferral = false; + ContentDialog? dialog = default; + switch (parameter) + { + case DialogMode.Input: + dialog = new ContentDialog() + { + Title = "Let's go ...", + PrimaryButtonText = "Ok :-)", + SecondaryButtonText = "Not OK :-(", + CloseButtonText = "Leave me alone!" + }; + + var viewModel = new CustomContentDialogViewModel(dialog); + dialog.Content = new ContentDialogInputExample() + { + DataContext = viewModel + }; + break; + case DialogMode.Deferal: + default: + dialog = new ContentDialog + { + PrimaryButtonText = PrimaryButtonText, + SecondaryButtonText = SecondaryButtonText, + CloseButtonText = CloseButtonText, + Title = DialogTitle, + Content = Content, + IsPrimaryButtonEnabled = IsPrimaryButtonEnabled, + IsSecondaryButtonEnabled = IsSecondaryButtonEnabled, + DefaultButton = ContentDialogDefaultButton, + FullSizeDesired = FullSizeDesired + }; + hasDeferral = parameter is DialogMode.Deferal; + break; + } + + if (hasDeferral) + { + dialog.PrimaryButtonClick += OnPrimaryButtonClick; + await dialog.ShowAsync(); + dialog.PrimaryButtonClick -= OnPrimaryButtonClick; + } + else + { + await dialog.ShowAsync(); + } + } + + private async void OnPrimaryButtonClick(object? sender, ContentDialogButtonClickEventArgs args) + { + var def = args.GetDeferral(); + await Task.Delay(3000); + def.Complete(); + } + + + + + //private string _title = "Title Here"; + private string _content = "Dialog message here (doesn't have to be a string, can be anything)"; + private string _primaryText = "Primary Button"; + private string _secondaryText = "Secondary Button"; + private string _closeText = "Close Button"; + private bool _fullSize; + private ContentDialogButton _defaultButton; + private bool _primaryEnabled = true; + private bool _secondaryEnabled = true; + private string? _dialogTitle = "Title Here"; +} diff --git a/samples/Avalonia.Labs.Catalog/ViewModels/CustomContentDialogViewModel.cs b/samples/Avalonia.Labs.Catalog/ViewModels/CustomContentDialogViewModel.cs new file mode 100644 index 0000000..0a07a9f --- /dev/null +++ b/samples/Avalonia.Labs.Catalog/ViewModels/CustomContentDialogViewModel.cs @@ -0,0 +1,85 @@ +using System; +using Avalonia.Labs.Controls; +using ReactiveUI; + +namespace Avalonia.Labs.Catalog.ViewModels; + +class CustomContentDialogViewModel : ViewModelBase +{ + private readonly ContentDialog dialog; + + public CustomContentDialogViewModel(ContentDialog dialog) + { + if (dialog is null) + { + throw new ArgumentNullException(nameof(dialog)); + } + + this.dialog = dialog; + dialog.Closed += DialogOnClosed; + } + + private void DialogOnClosed(object? sender, ContentDialogClosedEventArgs args) + { + dialog.Closed -= DialogOnClosed; + + var resultHint = new ContentDialog() + { + Content = $"You chose \"{args.Result}\"", + Title = "Result", + PrimaryButtonText = "Thanks" + }; + + _ = resultHint.ShowAsync(); + } + + private string? _UserInput; + + /// + /// Gets or sets the user input to check + /// + public string? UserInput + { + get => _UserInput; + set + { + this.RaiseAndSetIfChanged(ref _UserInput, value); + HandleUserInput(); + } + } + + private void HandleUserInput() + { + switch (UserInput?.ToLowerInvariant()) + { + case "accept": + case "ok": + dialog.Hide(ContentDialogResult.Primary); + break; + + case "dismiss": + case "not ok": + dialog.Hide(ContentDialogResult.Secondary); + break; + + case "cancel": + case "close": + case "hide": + dialog.Hide(); + break; + } + } + + private static readonly string[] _AvailableKeyWords = new[] + { + "Accept", + "OK", + "Dismiss", + "Not OK", + "Close", + "Cancel", + "Hide" +}; + + public string[] AvailableKeyWords => _AvailableKeyWords; +} diff --git a/samples/Avalonia.Labs.Catalog/Views/ContentDialogInputExample.axaml b/samples/Avalonia.Labs.Catalog/Views/ContentDialogInputExample.axaml new file mode 100644 index 0000000..dbed9aa --- /dev/null +++ b/samples/Avalonia.Labs.Catalog/Views/ContentDialogInputExample.axaml @@ -0,0 +1,20 @@ + + + Try out some magic keywords + + + + diff --git a/samples/Avalonia.Labs.Catalog/Views/ContentDialogInputExample.axaml.cs b/samples/Avalonia.Labs.Catalog/Views/ContentDialogInputExample.axaml.cs new file mode 100644 index 0000000..14a36fd --- /dev/null +++ b/samples/Avalonia.Labs.Catalog/Views/ContentDialogInputExample.axaml.cs @@ -0,0 +1,25 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Threading; + +namespace Avalonia.Labs.Catalog.Views; + +public partial class ContentDialogInputExample : UserControl +{ + public ContentDialogInputExample() + { + InitializeComponent(); + } + + private void InputField_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e) + { + // We will set the focus into our input field just after it got attached to the visual tree. + if (sender is InputElement inputElement) + { + Dispatcher.UIThread.InvokeAsync(() => + { + inputElement.Focus(NavigationMethod.Unspecified, KeyModifiers.None); + }); + } + } +} diff --git a/samples/Avalonia.Labs.Catalog/Views/ContentDialogView.axaml b/samples/Avalonia.Labs.Catalog/Views/ContentDialogView.axaml new file mode 100644 index 0000000..1248ab8 --- /dev/null +++ b/samples/Avalonia.Labs.Catalog/Views/ContentDialogView.axaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +