Files
Lattice/Lattice.UI.Docking.WinUI/Services/WinUIDockUIService.cs
2026-01-18 16:33:35 +03:00

167 lines
4.6 KiB
C#

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.
/// </summary>
public sealed class WinUIDockUIService : DockUIServiceBase
{
/// <inheritdoc/>
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";
// Регистрируем окно в трекере
Themes.WindowTracker.Register(window);
return window;
}
/// <inheritdoc/>
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
};
}
/// <inheritdoc/>
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();
}
/// <inheritdoc/>
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;
}
/// <inheritdoc/>
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;
}
/// <inheritdoc/>
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());
}
}
/// <inheritdoc/>
public override 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()
{
// Получаем XamlRoot из активного окна
foreach (var window in Themes.WindowTracker.Windows)
{
if (window.Content is FrameworkElement element)
{
return element.XamlRoot;
}
}
return null;
}
}