Files
Lattice/Lattice.Layout.UI.WinUI/Controls/WinUIItemControl.cs
2026-01-18 16:33:35 +03:00

135 lines
4.7 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 Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
namespace Lattice.Layout.UI.WinUI.Controls;
/// <summary>
/// Контрол для отображения содержимого конечного элемента раскладки.
/// Является контейнером для реального UI-контента, подставляемого через ContentResolver.
/// </summary>
public sealed class WinUIItemControl : ContentControl
{
/// <summary>
/// Идентификатор содержимого, связанного с данным элементом.
/// Используется для подстановки реального UI-контрола через ContentResolver.
/// </summary>
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));
/// <summary>
/// Делегат, который должен вернуть реальный UI-контент по ContentId.
/// Устанавливается WinUILayoutHost.
/// </summary>
public Func<string, UIElement?>? ContentResolver
{
get => (Func<string, UIElement?>?)GetValue(ContentResolverProperty);
set => SetValue(ContentResolverProperty, value);
}
public static readonly DependencyProperty ContentResolverProperty =
DependencyProperty.Register(
nameof(ContentResolver),
typeof(Func<string, UIElement?>),
typeof(WinUIItemControl),
new PropertyMetadata(null, OnContentResolverChanged));
/// <summary>
/// Вызывается, когда контент успешно загружен.
/// </summary>
public event Action<WinUIItemControl>? ContentLoaded;
/// <summary>
/// Вызывается, когда контент был очищен (Detach).
/// </summary>
public event Action<WinUIItemControl>? ContentCleared;
/// <summary>
/// Создаёт новый экземпляр <see cref="WinUIItemControl"/>.
/// </summary>
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();
}
/// <summary>
/// Пытается загрузить реальный контент по ContentId.
/// </summary>
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);
}
/// <summary>
/// Очищает контент (используется визуалом при Detach).
/// </summary>
public void ClearContent()
{
Content = CreatePlaceholder();
ContentCleared?.Invoke(this);
}
/// <summary>
/// Создаёт placeholder-контент, отображаемый до загрузки реального UI.
/// </summary>
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
}
};
}
}