using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
namespace Lattice.Layout.UI.WinUI.Controls;
///
/// Контрол для отображения содержимого конечного элемента раскладки.
/// Является контейнером для реального UI-контента, подставляемого через ContentResolver.
///
public sealed class WinUIItemControl : ContentControl
{
///
/// Идентификатор содержимого, связанного с данным элементом.
/// Используется для подстановки реального UI-контрола через ContentResolver.
///
public string? ContentId
{
get => (string?)GetValue(ContentIdProperty);
set => SetValue(ContentIdProperty, value);
}
public static readonly DependencyProperty ContentIdProperty =
DependencyProperty.Register(
nameof(ContentId),
typeof(string),
typeof(WinUIItemControl),
new PropertyMetadata(default(string), OnContentIdChanged));
///
/// Делегат, который должен вернуть реальный UI-контент по ContentId.
/// Устанавливается WinUILayoutHost.
///
public Func? ContentResolver
{
get => (Func?)GetValue(ContentResolverProperty);
set => SetValue(ContentResolverProperty, value);
}
public static readonly DependencyProperty ContentResolverProperty =
DependencyProperty.Register(
nameof(ContentResolver),
typeof(Func),
typeof(WinUIItemControl),
new PropertyMetadata(null, OnContentResolverChanged));
///
/// Вызывается, когда контент успешно загружен.
///
public event Action? ContentLoaded;
///
/// Вызывается, когда контент был очищен (Detach).
///
public event Action? ContentCleared;
///
/// Создаёт новый экземпляр .
///
public WinUIItemControl()
{
HorizontalContentAlignment = HorizontalAlignment.Stretch;
VerticalContentAlignment = VerticalAlignment.Stretch;
// Fallback-контент, если ContentResolver не установлен
Content = CreatePlaceholder();
}
private static void OnContentIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is WinUIItemControl control)
control.TryLoadContent();
}
private static void OnContentResolverChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is WinUIItemControl control)
control.TryLoadContent();
}
///
/// Пытается загрузить реальный контент по ContentId.
///
private void TryLoadContent()
{
if (ContentId is null || ContentResolver is null)
{
Content = CreatePlaceholder();
return;
}
var resolved = ContentResolver(ContentId);
if (resolved is null)
{
Content = CreatePlaceholder($"Контент '{ContentId}' не найден");
return;
}
Content = resolved;
ContentLoaded?.Invoke(this);
}
///
/// Очищает контент (используется визуалом при Detach).
///
public void ClearContent()
{
Content = CreatePlaceholder();
ContentCleared?.Invoke(this);
}
///
/// Создаёт placeholder-контент, отображаемый до загрузки реального UI.
///
private static UIElement CreatePlaceholder(string? message = null)
{
return new Border
{
Background = new SolidColorBrush(Microsoft.UI.Colors.Transparent),
BorderBrush = new SolidColorBrush(Microsoft.UI.Colors.Gray),
BorderThickness = new Thickness(1),
Padding = new Thickness(8),
Child = new TextBlock
{
Text = message ?? "Нет содержимого",
Opacity = 0.6,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
}
};
}
}