add Avalonia Dialogs
This commit is contained in:
47
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaDialogBase.Statics.cs
Normal file
47
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaDialogBase.Statics.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Pilz.UI.AvaloniaUI.Dialogs;
|
||||||
|
|
||||||
|
public partial class AvaloniaDialogBase
|
||||||
|
{
|
||||||
|
public static T Show<T>(string? title, object? icon, object? tag = null) where T : AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
return Show(CreatePanelInstance<T>(tag), title, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task<T> ShowDialog<T>(Window parent, string? title, object? icon, object? tag = null) where T : AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
return ShowDialog(CreatePanelInstance<T>(tag), parent, title, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Show<T>(T dialogPanel, string? title, object? icon) where T : AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
CreateForm(dialogPanel, title, icon, WindowStartupLocation.CenterScreen).Show();
|
||||||
|
return dialogPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<T> ShowDialog<T>(T dialogPanel, Window parent, string? title, object? icon) where T : AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
await CreateForm(dialogPanel, title, icon, WindowStartupLocation.CenterOwner).ShowDialog(parent);
|
||||||
|
return dialogPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T CreatePanelInstance<T>(object? tag) where T : AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
var dialogPanel = Activator.CreateInstance<T>();
|
||||||
|
dialogPanel.Tag = tag;
|
||||||
|
return dialogPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AvaloniaDialogBase CreateForm<T>(T dialogPanel, string? title, object? icon, WindowStartupLocation startPosition) where T : AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
var dialog = new AvaloniaDialogBase
|
||||||
|
{
|
||||||
|
Title = title,
|
||||||
|
Icon = icon as WindowIcon,
|
||||||
|
WindowStartupLocation = startPosition,
|
||||||
|
};
|
||||||
|
dialog.SetContent(dialogPanel);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaDialogBase.axaml
Normal file
8
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaDialogBase.axaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<Window 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"
|
||||||
|
x:Class="Pilz.UI.AvaloniaUI.Dialogs.AvaloniaDialogBase"
|
||||||
|
SizeToContent="WidthAndHeight">
|
||||||
|
</Window>
|
||||||
27
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaDialogBase.axaml.cs
Normal file
27
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaDialogBase.axaml.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Pilz.UI.AvaloniaUI.Dialogs;
|
||||||
|
|
||||||
|
public partial class AvaloniaDialogBase : Window
|
||||||
|
{
|
||||||
|
protected AvaloniaFlyoutBase? dialogPanel;
|
||||||
|
|
||||||
|
public AvaloniaFlyoutBase DialogPanel => dialogPanel ?? throw new NullReferenceException();
|
||||||
|
|
||||||
|
public AvaloniaDialogBase()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetContent(AvaloniaFlyoutBase content)
|
||||||
|
{
|
||||||
|
dialogPanel = content;
|
||||||
|
dialogPanel.OnClose += DialogPanelOnOnClose;
|
||||||
|
Content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DialogPanelOnOnClose(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Close(DialogPanel.Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaFlyoutBase.Statics.cs
Normal file
33
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaFlyoutBase.Statics.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Pilz.UI.AvaloniaUI.Dialogs;
|
||||||
|
|
||||||
|
public partial class AvaloniaFlyoutBase
|
||||||
|
{
|
||||||
|
// public static void Show<T>(Control controlToAssociate, object? tag = null)
|
||||||
|
// {
|
||||||
|
// Show<T>(controlToAssociate, null, null, tag: tag);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void Show<T>(Control controlToAssociate, string? title, RadSvgImage? icon, object? tag = null)
|
||||||
|
// {
|
||||||
|
// Show(controlToAssociate, typeof(T), title, icon, tag: tag);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void Show(Control controlToAssociate, Type flyoutContentType, string? title, RadSvgImage? icon, object? tag = null)
|
||||||
|
// {
|
||||||
|
// tagToAssign = tag;
|
||||||
|
// titleToAssing = title;
|
||||||
|
// iconToAssign = icon;
|
||||||
|
// ParentContext = controlToAssociate;
|
||||||
|
// CloseFlyout(); // Ensure it's closed!
|
||||||
|
// RadFlyoutManager.Show(controlToAssociate, flyoutContentType);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// protected static void CloseFlyout()
|
||||||
|
// {
|
||||||
|
// if (typeof(RadFlyoutManager).GetField("flyoutInstance", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).GetValue(null) is FlyoutScreen instance
|
||||||
|
// && instance.IsActive)
|
||||||
|
// RadFlyoutManager.Close();
|
||||||
|
// }
|
||||||
|
}
|
||||||
78
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaFlyoutBase.axaml
Normal file
78
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaFlyoutBase.axaml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<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:controls="https://git.pilzinsel64.de/pilz-framework/pilz"
|
||||||
|
xmlns:dialogs="clr-namespace:Pilz.UI.AvaloniaUI.Dialogs"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Pilz.UI.AvaloniaUI.Dialogs.AvaloniaFlyoutBase">
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
|
||||||
|
<!-- StackPanel: Header -->
|
||||||
|
<StackPanel
|
||||||
|
x:Name="StackPanelHeader"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Margin="3"
|
||||||
|
IsVisible="False"
|
||||||
|
>
|
||||||
|
|
||||||
|
<Image
|
||||||
|
x:Name="ImageTitle"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
x:Name="LabelTitle"
|
||||||
|
/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Panel: Content -->
|
||||||
|
<ContentPresenter
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Margin="3"
|
||||||
|
Content="{Binding MainContent, RelativeSource={RelativeSource AncestorType=dialogs:AvaloniaFlyoutBase}}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- StackPanel: Footer -->
|
||||||
|
<Grid
|
||||||
|
x:Name="StackPanelFooter"
|
||||||
|
RowDefinitions="Auto"
|
||||||
|
ColumnDefinitions="*,Auto,Auto"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
>
|
||||||
|
<ContentPresenter
|
||||||
|
Grid.Column="0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Margin="3"
|
||||||
|
Content="{Binding FooterContent, RelativeSource={RelativeSource AncestorType=dialogs:AvaloniaFlyoutBase}}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Button: Okay -->
|
||||||
|
<controls:ImageButton
|
||||||
|
Grid.Column="1"
|
||||||
|
x:Name="ButtonOkay"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Margin="3"
|
||||||
|
Text="Okay"
|
||||||
|
Click="ButtonOkay_OnClick"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Button: Cancel -->
|
||||||
|
<controls:ImageButton
|
||||||
|
Grid.Column="2"
|
||||||
|
x:Name="ButtonCancel"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Margin="3"
|
||||||
|
Text="Cancel"
|
||||||
|
Click="ButtonCancel_OnClick"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
197
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaFlyoutBase.axaml.cs
Normal file
197
Pilz.UI.AvaloniaUI/Dialogs/AvaloniaFlyoutBase.axaml.cs
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
|
namespace Pilz.UI.AvaloniaUI.Dialogs;
|
||||||
|
|
||||||
|
public partial class AvaloniaFlyoutBase : UserControl
|
||||||
|
{
|
||||||
|
protected readonly BackgroundWorker bgWorker_LoadData = new();
|
||||||
|
|
||||||
|
public delegate void OnCloseEventHandler(object? sender, EventArgs e);
|
||||||
|
|
||||||
|
public event OnCloseEventHandler? OnClose;
|
||||||
|
|
||||||
|
public static IImage? CancelImage { get; set; } = null;
|
||||||
|
public static IImage? ConfirmImage { get; set; } = null;
|
||||||
|
|
||||||
|
public static readonly StyledProperty<object?> MainContentProperty = AvaloniaProperty.Register<AvaloniaFlyoutBase, object?>(nameof(MainContent));
|
||||||
|
public static readonly StyledProperty<object?> FooterContentProperty = AvaloniaProperty.Register<AvaloniaFlyoutBase, object?>(nameof(FooterContent));
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
|
public object? Result { get; protected set; }
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public bool RegisterDialogAccept { get; set; } = true;
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public bool RegisterDialogCancel { get; set; } = true;
|
||||||
|
|
||||||
|
protected AvaloniaFlyoutBase()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
CancelButtonImage = CancelImage;
|
||||||
|
ConfirmButtonImage = ConfirmImage;
|
||||||
|
|
||||||
|
bgWorker_LoadData.DoWork += BgWorker_LoadData_DoWork;
|
||||||
|
bgWorker_LoadData.RunWorkerCompleted += BgWorker_LoadData_RunWorkerCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? MainContent
|
||||||
|
{
|
||||||
|
get => GetValue(MainContentProperty);
|
||||||
|
set => SetValue(MainContentProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? FooterContent
|
||||||
|
{
|
||||||
|
get => GetValue(FooterContentProperty);
|
||||||
|
set => SetValue(FooterContentProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public virtual bool ActionPanelVisible
|
||||||
|
{
|
||||||
|
get => StackPanelFooter.IsVisible;
|
||||||
|
set => StackPanelFooter.IsVisible = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public virtual bool CancelButtonVisible
|
||||||
|
{
|
||||||
|
get => ButtonCancel.IsVisible;
|
||||||
|
set => ButtonCancel.IsVisible = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public virtual bool ConfirmButtonVisible
|
||||||
|
{
|
||||||
|
get => ButtonOkay.IsVisible;
|
||||||
|
set => ButtonOkay.IsVisible = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public virtual bool CancelButtonEnable
|
||||||
|
{
|
||||||
|
get => ButtonCancel.IsEnabled;
|
||||||
|
set => ButtonCancel.IsEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(true)]
|
||||||
|
public virtual bool ConfirmButtonEnable
|
||||||
|
{
|
||||||
|
get => ButtonOkay.IsEnabled;
|
||||||
|
set => ButtonOkay.IsEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(null)]
|
||||||
|
public virtual IImage? CancelButtonImage
|
||||||
|
{
|
||||||
|
get => ButtonCancel.ImageSource;
|
||||||
|
set => ButtonCancel.ImageSource = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(null)]
|
||||||
|
public virtual IImage? ConfirmButtonImage
|
||||||
|
{
|
||||||
|
get => ButtonOkay.ImageSource;
|
||||||
|
set => ButtonOkay.ImageSource = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
[DefaultValue("Okay")]
|
||||||
|
public virtual string? ConfirmButtonText
|
||||||
|
{
|
||||||
|
get => ButtonOkay.Text;
|
||||||
|
set => ButtonOkay.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
[DefaultValue("Cancel")]
|
||||||
|
public virtual string? CancelButtonText
|
||||||
|
{
|
||||||
|
get => ButtonCancel.Text;
|
||||||
|
set => ButtonCancel.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
[DefaultValue("")]
|
||||||
|
public virtual string? Title
|
||||||
|
{
|
||||||
|
get => LabelTitle.Text;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
LabelTitle.Text = value;
|
||||||
|
SetShowTitlePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultValue(null)]
|
||||||
|
public virtual IImage? TitleIcon
|
||||||
|
{
|
||||||
|
get => ImageTitle.Source;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ImageTitle.Source = value;
|
||||||
|
SetShowTitlePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void BgWorker_LoadData_DoWork(object? sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
OnLoadData(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void BgWorker_LoadData_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
OnLoadDataCompleted(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void LoadData()
|
||||||
|
{
|
||||||
|
bgWorker_LoadData.RunWorkerAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void LoadData(object? argument)
|
||||||
|
{
|
||||||
|
bgWorker_LoadData.RunWorkerAsync(argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnLoadData(DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnLoadDataCompleted(RunWorkerCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Close(object? result)
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
OnClose?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool ValidateOK()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void SetShowTitlePanel()
|
||||||
|
{
|
||||||
|
StackPanelHeader.IsVisible = !string.IsNullOrWhiteSpace(Title) || TitleIcon != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ButtonOkay_OnClick(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (ValidateOK())
|
||||||
|
Close(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ButtonCancel_OnClick(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Close(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
Pilz/EnvironmentEx.cs
Normal file
27
Pilz/EnvironmentEx.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using Pilz.Runtime;
|
||||||
|
|
||||||
|
namespace Pilz;
|
||||||
|
|
||||||
|
public static class EnvironmentEx
|
||||||
|
{
|
||||||
|
private static string? processPath = null;
|
||||||
|
|
||||||
|
public static string? ProcessPath => processPath ??= GetProcessPath();
|
||||||
|
|
||||||
|
private static string? GetProcessPath()
|
||||||
|
{
|
||||||
|
if (RuntimeInformationsEx.IsOSPlatform(OSType.Linux, false)
|
||||||
|
&& Environment.GetEnvironmentVariable("APPIMAGE") is { } appImagePath
|
||||||
|
&& !string.IsNullOrWhiteSpace(appImagePath))
|
||||||
|
return appImagePath;
|
||||||
|
|
||||||
|
#if NET8_0_OR_GREATER
|
||||||
|
if (Environment.ProcessPath is { } processPath
|
||||||
|
&& !string.IsNullOrWhiteSpace(processPath))
|
||||||
|
return processPath;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Process.GetCurrentProcess().MainModule?.FileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>annotations</Nullable>
|
<Nullable>annotations</Nullable>
|
||||||
<Version>2.5.3</Version>
|
<Version>2.6.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||||
|
|||||||
@@ -76,4 +76,17 @@ public static class RuntimeInformationsEx
|
|||||||
{
|
{
|
||||||
return (checkRealOS ? RealOSType : OSType) == os;
|
return (checkRealOS ? RealOSType : OSType) == os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetRuntimeIdentifier()
|
||||||
|
{
|
||||||
|
var arch = RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant();
|
||||||
|
var os = OSType switch
|
||||||
|
{
|
||||||
|
OSType.Windows => "win",
|
||||||
|
OSType.Linux => "linux",
|
||||||
|
OSType.OSX => "osx",
|
||||||
|
_ => throw new NotSupportedException(),
|
||||||
|
};
|
||||||
|
return $"{os}-{arch}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user