Files
Lattice/Lattice.UI.Docking.WinUI/Services/WinUIDockUIService.cs
2026-02-01 09:26:13 +03:00

163 lines
4.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Lattice.UI.Docking.Abstractions;
using Lattice.UI.Docking.Services;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Threading.Tasks;
namespace Lattice.UI.Docking.WinUI.Services;
/// <summary>
/// Реализация UI-сервиса для платформы WinUI.
/// Инкапсулирует платформенно-зависимые операции, такие как создание окон,
/// показ диалогов и синхронизация с UI-потоком.
/// </summary>
public sealed class WinUIDockUIService : DockUIServiceBase, IDockUIService
{
public override object CreateMainWindow(IDockHost host)
{
if (host is not FrameworkElement hostElement)
throw new ArgumentException("Host must be a FrameworkElement", nameof(host));
var window = new Window();
window.Content = hostElement;
window.AppWindow.Title = "Lattice IDE";
// Регистрируем окно в трекере
Lattice.Themes.WindowTracker.Register(window);
return window;
}
public override bool? ShowDialog(string title, object content)
{
if (content is not FrameworkElement contentElement)
return null;
var dialog = new ContentDialog
{
Title = title,
Content = contentElement,
PrimaryButtonText = "OK",
CloseButtonText = "Cancel",
XamlRoot = GetActiveXamlRoot()
};
var result = dialog.ShowAsync();
return result.GetAwaiter().GetResult() switch
{
ContentDialogResult.Primary => true,
ContentDialogResult.Secondary => false,
_ => null
};
}
public override void ShowMessage(string message, string caption)
{
var dialog = new ContentDialog
{
Title = caption,
Content = new TextBlock { Text = message },
PrimaryButtonText = "OK",
XamlRoot = GetActiveXamlRoot()
};
dialog.ShowAsync();
}
public override bool Confirm(string message, string caption)
{
var dialog = new ContentDialog
{
Title = caption,
Content = new TextBlock { Text = message },
PrimaryButtonText = "Yes",
SecondaryButtonText = "No",
XamlRoot = GetActiveXamlRoot()
};
var result = dialog.ShowAsync().GetAwaiter().GetResult();
return result == ContentDialogResult.Primary;
}
public override string? Prompt(string prompt, string? defaultValue = null)
{
var textBox = new TextBox
{
Text = defaultValue ?? string.Empty,
Width = 300,
Height = 32
};
var dialog = new ContentDialog
{
Title = prompt,
Content = textBox,
PrimaryButtonText = "OK",
SecondaryButtonText = "Cancel",
XamlRoot = GetActiveXamlRoot()
};
var result = dialog.ShowAsync().GetAwaiter().GetResult();
return result == ContentDialogResult.Primary ? textBox.Text : null;
}
public override void InvokeOnUIThread(Action action)
{
if (action == null) return;
var dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();
if (dispatcherQueue.HasThreadAccess)
{
action();
}
else
{
dispatcherQueue.TryEnqueue(() => action());
}
}
/// <summary>
/// Выполняет указанную асинхронную функцию в UI-потоке.
/// </summary>
public async Task InvokeOnUIThreadAsync(Func<Task> action)
{
if (action == null) return;
var dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();
if (dispatcherQueue.HasThreadAccess)
{
await action();
}
else
{
var tcs = new TaskCompletionSource<bool>();
dispatcherQueue.TryEnqueue(async () =>
{
try
{
await action();
tcs.SetResult(true);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
});
await tcs.Task;
}
}
private XamlRoot? GetActiveXamlRoot()
{
foreach (var window in Lattice.Themes.WindowTracker.Windows)
{
if (window.Content is FrameworkElement element)
{
return element.XamlRoot;
}
}
return null;
}
}