You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
6.5 KiB

using Avalonia;
using Avalonia.Controls;
using Avalonia.Platform;
using EC.Util.Common;
using Material.Dialog;
using Material.Dialog.Icons;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
namespace JiLinApp.Core.Avalonia;
public static class ControlsUtil
{
#region Controls
/// <summary>
/// 查找子控件
/// </summary>
/// <typeparam name="T">控件类型</typeparam>
/// <param name="parent">父控件依赖对象</param>
/// <param name="list">子控件列表</param>
public static void FindChild<T>(Control parent, ref List<T> list) where T : Control
{
if (parent == null) return;
if (parent is Panel pParent)
{
foreach (Control item in pParent.Children)
{
if (item is Panel panel) FindChild(panel, ref list);
else if (item is T child) list.Add(child);
}
}
else if (parent is Decorator dParent)
{
if (dParent.Child != null) FindChild(dParent.Child, ref list);
}
}
public static Window? GetWindow(Control control)
{
Control? temp = control;
while (temp?.Parent != null)
{
if (temp.Parent is Window w) return w;
else temp = temp.Parent is Control c ? c : null;
}
return null;
}
public static bool TryGetWindow(Control control, out Window? window)
{
Control? temp = control;
window = null;
while (temp?.Parent != null)
{
if (temp.Parent is Window w) { window = w; break; }
else temp = temp.Parent is Control c ? c : null;
}
return window != null;
}
public static string GetText(this TextBox tb)
{
return tb.Text ?? string.Empty;
}
public static bool GetText(this TextBox tb, out string? text)
{
text = tb.Text;
return text != null;
}
public static string GetText(this ComboBox cbx)
{
string? val = string.Empty;
var item = cbx.SelectedItem;
if (item == null) return val;
if (item is Control)
{
if (ReflectUtil.GetProperty(item, "Content", out object? content)) val = content?.ToString();
else if (ReflectUtil.GetProperty(item, "Text", out string? text)) val = text;
}
else val = item.ToString();
return val ?? string.Empty;
}
public static bool GetText(this ComboBox cbx, out string? val)
{
var item = cbx.SelectedItem;
if (item is Control)
{
if (ReflectUtil.GetProperty(item, "Content", out object? content)) val = content?.ToString();
else if (ReflectUtil.GetProperty(item, "Text", out string? text)) val = text;
else val = null;
}
else val = item?.ToString();
return val != null;
}
#endregion Controls
#region Dialog
public static async Task<DialogResult> ShowDialog(Window? window, string title = "Info", string message = "")
{
if (window == null) return DialogResult.NoResult;
var dialog = DialogHelper.CreateAlertDialog(new AlertDialogBuilderParams
{
Borderless = true,
Width = 300,
DialogHeaderIcon = DialogIconKind.Info,
ContentHeader = title,
SupportingText = message,
StartupLocation = WindowStartupLocation.CenterOwner,
});
return await dialog.ShowDialog(window);
}
public static async Task<DialogResult> ShowWarnDialog(Window? window, string title = "Warning", string message = "")
{
if (window == null) return DialogResult.NoResult;
var dialog = DialogHelper.CreateAlertDialog(new AlertDialogBuilderParams
{
Borderless = true,
Width = 300,
DialogHeaderIcon = DialogIconKind.Warning,
ContentHeader = title,
SupportingText = message,
StartupLocation = WindowStartupLocation.CenterOwner,
});
return await dialog.ShowDialog(window);
}
#endregion Dialog
#region AvaloniaLocator.Current.GetService
private static AvaloniaLocator? _locator;
private static MethodInfo? _getService;
public static T? GetService<T>()
{
if (_locator == null)
{
FieldInfo[] fieldInfos = typeof(AvaloniaLocator).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo item in fieldInfos)
if (item.FieldType.IsAssignableFrom(typeof(AvaloniaLocator))) { _locator = (AvaloniaLocator?)item.GetValue(null); break; }
}
if (_getService == null)
{
MethodInfo[] methodInfos = typeof(AvaloniaLocator).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo item in methodInfos) if (item.Name.Equals("GetService")) { _getService = item; break; }
}
return (T?)_getService?.Invoke(_locator, new object[] { typeof(T) });
}
#endregion AvaloniaLocator.Current.GetService
#region Avalonia.X11
private static IWindowingPlatform? Platform { get; set; }
private static object? X11 { get; set; }
private static object? Atoms { get; set; }
public static IntPtr GetHandle(IWindowImpl? platformImpl)
{
IntPtr handle = platformImpl != null ? ReflectUtil.GetField<IntPtr>(platformImpl, "_handle") : IntPtr.Zero;
return handle;
}
public static IntPtr GetDisplay(IWindowImpl platformImpl)
{
IWindowingPlatform? _platform = Platform ??= ReflectUtil.GetField<IWindowingPlatform>(platformImpl, "_platform");
if (_platform == null) return IntPtr.Zero;
IntPtr display = ReflectUtil.GetProperty<IntPtr>(_platform, "Display");
return display;
}
public static IntPtr GetAtom(IWindowImpl platformImpl, string name)
{
IWindowingPlatform? _platform = Platform ??= ReflectUtil.GetField<IWindowingPlatform>(platformImpl, "_platform");
if (_platform == null) return IntPtr.Zero;
object? _x11 = X11 ??= ReflectUtil.GetProperty<object>(_platform, "Info");
if (_x11 == null) return IntPtr.Zero;
object? _atoms = Atoms ??= ReflectUtil.GetProperty<object>(_x11, "Atoms");
if (_atoms == null) return IntPtr.Zero;
IntPtr _atom = ReflectUtil.RunMethod<IntPtr>(_atoms, "GetAtom", new object[] { name });
return _atom;
}
#endregion Avalonia.X11
}