Skip to content

Commit

Permalink
Merge pull request #27 from workgroupengineering/features/Controls/Co…
Browse files Browse the repository at this point in the history
…ntentDialog

feat: ContentDialog
  • Loading branch information
emmauss authored Jul 19, 2023
2 parents 0819830 + 1e353c2 commit e062b17
Show file tree
Hide file tree
Showing 23 changed files with 2,320 additions and 31 deletions.
156 changes: 156 additions & 0 deletions samples/Avalonia.Labs.Catalog/ViewModels/ContentDialogViewModel.cs
Original file line number Diff line number Diff line change
@@ -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<ContentDialogButton>();

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";
}
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// Gets or sets the user input to check
/// </summary>
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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Avalonia.Labs.Catalog.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Padding="0, 10"
x:DataType="vm:CustomContentDialogViewModel"
x:Class="Avalonia.Labs.Catalog.Views.ContentDialogInputExample">
<StackPanel Spacing="10" MinWidth="400">
<TextBlock>Try out some magic keywords</TextBlock>
<AutoCompleteBox FilterMode="StartsWithOrdinal"
Watermark="Write a keyword, for example 'ok', 'not ok' or 'hide'"
Text="{CompiledBinding UserInput}"
ItemsSource="{Binding AvailableKeyWords}"
AttachedToVisualTree="InputField_OnAttachedToVisualTree" />
<TextBox Text="" AcceptsReturn="True"
/>
</StackPanel>
</UserControl>
Original file line number Diff line number Diff line change
@@ -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);
});
}
}
}
58 changes: 58 additions & 0 deletions samples/Avalonia.Labs.Catalog/Views/ContentDialogView.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:vm="using:Avalonia.Labs.Catalog.ViewModels"
x:Class="Avalonia.Labs.Catalog.Views.ContentDialogView">
<DockPanel>
<StackPanel Orientation="Vertical"
Spacing="4"
MaxWidth="250"
DockPanel.Dock="Right">
<Expander Header="Enabled Buttons" IsExpanded="True">
<StackPanel Orientation="Vertical">
<CheckBox Content="IsPrimaryButtonEnabled" IsChecked="{Binding IsPrimaryButtonEnabled}"/>
<CheckBox Content="IsSecondaryButtonEnabled" IsChecked="{Binding IsSecondaryButtonEnabled}"/>
</StackPanel>
</Expander>
<Expander Header="Default Button">
<ComboBox Name="DefButtonSelector" MinWidth="90"
ItemsSource="{Binding ContentDialogButtons}"
SelectedItem="{Binding ContentDialogDefaultButton}" />
</Expander>
<Expander Header="Content">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Text="Title"/>
<TextBox Text="{Binding Title}" />
<TextBlock Text="Content"/>
<TextBox Text="{Binding Content}" />
<TextBlock Text="PrimaryButtonText"/>
<TextBox Text="{Binding PrimaryButtonText}" />
<TextBlock Text="SecondaryButtonText"/>
<TextBox Text="{Binding SecondaryButtonText}" />
<TextBlock Text="CloseButtonText"/>
<TextBox Text="{Binding CloseButtonText}" />
</StackPanel>
</Expander>

<StackPanel Orientation="Vertical" Margin="20 0">
<CheckBox Content="FullSizeDesired" IsChecked="{Binding FullSizeDesired}"
ToolTip.ShowDelay="100"
ToolTip.Tip="Full size stretches the dialog to &quot;full screen&quot;. &#x0a; Though, it just stretches it to the height size of a Content Dialog. &#x0a;"/>
</StackPanel>
</StackPanel>

<StackPanel Spacing="8">
<Button Content="Launch ContentDialog"
Command="{Binding LaunchDialog}"
CommandParameter="{x:Static vm:DialogMode.Default}" />
<Button Content="Launch ContentDialog with Primary Button deferral"
Command="{Binding LaunchDialog}"
CommandParameter="{x:Static vm:DialogMode.Deferal}" />
<Button Content="Show Input"
Command="{Binding LaunchDialog}"
CommandParameter="{x:Static vm:DialogMode.Input}"/>
</StackPanel>
</DockPanel>
</UserControl>
13 changes: 13 additions & 0 deletions samples/Avalonia.Labs.Catalog/Views/ContentDialogView.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace Avalonia.Labs.Catalog.Views;

public partial class ContentDialogView : UserControl
{
public ContentDialogView()
{
InitializeComponent();
}
}
11 changes: 11 additions & 0 deletions samples/Avalonia.Labs.Catalog/Views/WelcomeView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@
<Label FontSize="18"
VerticalAlignment="Center">Async Image</Label>
</Button>
<Button HorizontalAlignment="Stretch"
Height="60"
Command="{Binding NavigateTo}"
CornerRadius="10"
Margin="0,5">
<Button.CommandParameter>
<viewModels:ContentDialogViewModel/>
</Button.CommandParameter>
<Label FontSize="18"
VerticalAlignment="Center">ContentDialog</Label>
</Button>
<Button HorizontalAlignment="Stretch"
Height="60"
Command="{Binding NavigateTo}"
Expand Down
10 changes: 10 additions & 0 deletions src/Avalonia.Labs.Controls/Avalonia.Labs.Controls.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,14 @@
<AvaloniaResource Include="**/*.xaml" />
<AvaloniaResource Include="**/*.axaml" />
</ItemGroup>

<ItemGroup>
<AvaloniaXaml Remove="Themes\Controls\ContentDialog.axaml" />
</ItemGroup>

<ItemGroup>
<AvaloniaResource Update="Themes\Controls\ContentDialog.axaml">
<SubType>Designer</SubType>
</AvaloniaResource>
</ItemGroup>
</Project>
Loading

0 comments on commit e062b17

Please sign in to comment.