167 lines
4.6 KiB
C#
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;
|
|
}
|
|
} |