Files
ShrlAlgoToolkit/NeoUI/Melskin/Controls/IconElement.xaml.cs

363 lines
14 KiB
C#
Raw Normal View History

2026-01-02 17:30:30 +08:00
using VariaStudio.Assets;
2025-08-20 12:10:35 +08:00
2026-01-02 17:30:30 +08:00
namespace VariaStudio.Controls;
2025-08-20 12:10:35 +08:00
/// <summary>
/// 图标控件:支持 MaterialSymbol / Glyph / ImageSource / Geometry / Drawing / DrawingBrush。
/// 使用 DataTemplate 按需创建视觉树,属性变化即时切换模板。
/// </summary>
/// <example>
/// <code lang="xaml">
/// <!-- MaterialSymbol -->
///<IconElement Symbol = "Search" FontSize="20"/>
2025-08-20 12:10:35 +08:00
///<!-- Glyph -->
///<IconElement ContentType = "Glyph"
2025-08-20 12:10:35 +08:00
/// FontFamily="pack://application:,,,/YourAsm;component/Assets/Fonts/#YourFont"
/// Glyph="&#xE001;" FontSize="20"/>
///<!-- Image -->
2026-01-02 17:30:30 +08:00
///<IconElement ImageSource = "/VariaStudio;component/Assets/Images/add.png" Width="24" Height="24"/>
2025-08-20 12:10:35 +08:00
///<!-- Geometry -->
///<IconElement Geometry = "M0,0 L10,0 10,10 0,10Z"
2025-08-20 12:10:35 +08:00
/// GeometryFill="DodgerBlue"
/// Width="16" Height="16"/>
///<!-- Drawing(代码设置 Drawing) -->
///<IconElement Width="24" Height="24"/>
2025-08-20 12:10:35 +08:00
///<!-- DrawingBrush -->
///<IconElement DrawingBrush = "{StaticResource SomeDrawingBrush}" Width="24" Height="24"/>
2025-08-20 12:10:35 +08:00
/// </code>
/// </example>
public class IconElement : Control
{
static IconElement()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(IconElement),
new FrameworkPropertyMetadata(typeof(IconElement)));
}
2025-08-24 13:49:55 +08:00
/// <summary>
/// 用于显示图标的控件。可以通过设置属性来指定图标的具体样式和内容。
/// </summary>
public IconElement()
{
}
2025-08-20 12:10:35 +08:00
#region
/// <summary>
/// 用于定义图标内容类型的枚举。此枚举支持多种类型的内容包括自动检测、Material 符号、字形、图像、几何图形、绘图以及画刷。
/// </summary>
public enum IconContentType
{
/// <summary>
/// 表示图标内容类型将自动检测。当设置此枚举值时,系统会根据提供的内容自动选择最合适的图标渲染方式。
/// </summary>
Auto,
/// <summary>
/// 表示图标内容为Material符号类型。当设置此枚举值时表示图标将使用Material设计风格的符号来渲染。
/// </summary>
Material,
/// <summary>
/// 表示图标内容为字形类型。当设置此枚举值时,表示图标将使用字形数据来渲染。
/// </summary>
Glyph,
/// <summary>
/// 表示图标内容为图像类型。当设置此枚举值时,表示图标将使用图像数据来渲染。
/// </summary>
Image,
/// <summary>
/// 表示图标内容类型为几何图形。当ContentType设置为此值时IconElement将使用指定的几何图形来渲染图标。
/// </summary>
Geometry,
/// <summary>
/// 表示图标内容为绘图类型。当设置此枚举值时,表示图标将使用绘图数据来渲染。
/// </summary>
Drawing,
/// <summary>
/// 表示图标内容类型为画刷。当ContentType设置为此值时IconElement将使用指定的画刷来渲染图标。
/// </summary>
Brush
}
#endregion
#region
/// <summary>
/// 用于获取或设置图标元素的符号。此属性定义了IconElement将显示的具体MaterialSymbol。
/// </summary>
public static readonly DependencyProperty SymbolProperty = DependencyProperty.Register(
nameof(Symbol), typeof(MaterialSymbol), typeof(IconElement),
new PropertyMetadata(MaterialSymbol.CR, OnContentChanged));
2025-08-20 12:10:35 +08:00
/// <summary>
/// 获取或设置图标元素的符号。此属性指定了IconElement将要展示的具体MaterialSymbol。
/// </summary>
public MaterialSymbol Symbol
{
get => (MaterialSymbol)GetValue(SymbolProperty);
set => SetValue(SymbolProperty, value);
}
/// <summary>
/// 用于获取或设置图标的字形。此属性定义了IconElement将显示的具体字形字符串。
/// </summary>
public static readonly DependencyProperty GlyphProperty = DependencyProperty.Register(
nameof(Glyph), typeof(string), typeof(IconElement),
new PropertyMetadata(string.Empty, OnContentChanged));
/// <summary>
2025-08-24 13:49:55 +08:00
/// 获取或设置图标元素的字形代码。此属性定义了IconElement将显示的具体字形通常用于指定字体图标。
2025-08-20 12:10:35 +08:00
/// </summary>
public string? Glyph
2025-08-20 12:10:35 +08:00
{
get => (string)GetValue(GlyphProperty);
set => SetValue(GlyphProperty, value);
}
/// <summary>
/// 用于获取或设置图像源。此属性定义了IconElement将显示的具体图像。
/// </summary>
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register(
nameof(ImageSource), typeof(ImageSource), typeof(IconElement),
new PropertyMetadata(null, OnContentChanged));
/// <summary>
/// 用于获取或设置图标元素的图像源。此属性允许为IconElement指定一个图像该图像将作为控件的内容显示。
/// </summary>
public ImageSource? ImageSource
{
get => (ImageSource?)GetValue(ImageSourceProperty);
set => SetValue(ImageSourceProperty, value);
}
/// <summary>
/// 用于获取或设置图标元素的几何图形。此属性允许为IconElement指定一个自定义的Geometry对象以显示特定形状或路径。
/// </summary>
public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register(
nameof(Geometry), typeof(Geometry), typeof(IconElement),
new PropertyMetadata(null, OnContentChanged));
/// <summary>
/// 用于获取或设置图标元素的几何图形。此属性允许定义一个Geometry对象该对象将被用来渲染IconElement中的形状。
/// </summary>
public Geometry? Geometry
{
get => (Geometry?)GetValue(GeometryProperty);
set => SetValue(GeometryProperty, value);
}
/// <summary>
/// 用于获取或设置图标元素的绘图。此属性定义了IconElement将显示的具体绘图内容。
/// </summary>
public static readonly DependencyProperty DrawingProperty = DependencyProperty.Register(
nameof(Drawing), typeof(Drawing), typeof(IconElement),
new PropertyMetadata(null, OnContentChanged));
/// <summary>
/// 用于获取或设置图标元素的绘图。此属性允许您指定一个Drawing对象该对象将作为图标的内容进行显示。
/// </summary>
public Drawing? Drawing
{
get => (Drawing?)GetValue(DrawingProperty);
set => SetValue(DrawingProperty, value);
}
/// <summary>
/// 用于获取或设置图标元素的绘图刷。此属性定义了IconElement将使用的DrawingBrush以控制图标显示时的填充样式。
/// </summary>
public static readonly DependencyProperty DrawingBrushProperty = DependencyProperty.Register(
nameof(DrawingBrush), typeof(DrawingBrush), typeof(IconElement),
new PropertyMetadata(null, OnContentChanged));
/// <summary>
///
/// </summary>
public DrawingBrush? DrawingBrush
{
get => (DrawingBrush?)GetValue(DrawingBrushProperty);
set => SetValue(DrawingBrushProperty, value);
}
/// <summary>
/// 用于获取或设置图像的拉伸模式。此属性决定了IconElement中的图像如何被拉伸以填充可用空间。
/// </summary>
public static readonly DependencyProperty ImageStretchProperty = DependencyProperty.Register(
nameof(ImageStretch), typeof(Stretch), typeof(IconElement),
new PropertyMetadata(Stretch.Uniform));
/// <summary>
/// 用于获取或设置图像的拉伸模式。此属性定义了图标元素中图像如何适应其布局区域。
/// </summary>
public Stretch ImageStretch
{
get => (Stretch)GetValue(ImageStretchProperty);
set => SetValue(ImageStretchProperty, value);
}
/// <summary>
/// 用于获取或设置几何图形的填充颜色。此属性定义了应用于几何图形内部的颜色刷。
/// </summary>
public static readonly DependencyProperty GeometryFillProperty = DependencyProperty.Register(
nameof(GeometryFill), typeof(Brush), typeof(IconElement),
new PropertyMetadata(Brushes.Black));
/// <summary>
/// 用于获取或设置几何图形填充的颜色或图案。此属性定义了IconElement中几何图形的填充样式。
/// </summary>
public Brush GeometryFill
{
get => (Brush)GetValue(GeometryFillProperty);
set => SetValue(GeometryFillProperty, value);
}
/// <summary>
/// 用于获取或设置几何图形描边的画刷。此属性定义了应用于几何图形描边的颜色和样式。
/// </summary>
public static readonly DependencyProperty GeometryStrokeProperty = DependencyProperty.Register(
nameof(GeometryStroke), typeof(Brush), typeof(IconElement),
new PropertyMetadata(null));
/// <summary>
/// 用于获取或设置几何图形的描边画刷。此属性定义了IconElement中几何图形的描边样式。
/// </summary>
public Brush? GeometryStroke
{
get => (Brush?)GetValue(GeometryStrokeProperty);
set => SetValue(GeometryStrokeProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty GeometryStrokeThicknessProperty = DependencyProperty.Register(
nameof(GeometryStrokeThickness), typeof(double), typeof(IconElement),
new PropertyMetadata(1d));
/// <summary>
///
/// </summary>
public double GeometryStrokeThickness
{
get => (double)GetValue(GeometryStrokeThicknessProperty);
set => SetValue(GeometryStrokeThicknessProperty, value);
}
/// <summary>
/// 用于获取或设置图标元素的内容类型。此属性定义了IconElement将使用哪种类型的资源来显示内容例如Material符号、Glyph字符、图像等。
/// </summary>
public static readonly DependencyProperty ContentTypeProperty = DependencyProperty.Register(
nameof(ContentType), typeof(IconContentType), typeof(IconElement),
new PropertyMetadata(IconContentType.Auto, OnContentChanged));
/// <summary>
/// 用于获取或设置图标元素的内容类型。此属性定义了IconElement将使用的具体内容类型如Material、Glyph、Image等。
/// </summary>
public IconContentType ContentType
{
get => (IconContentType)GetValue(ContentTypeProperty);
set => SetValue(ContentTypeProperty, value);
}
private static readonly DependencyPropertyKey EffectiveContentTypePropertyKey =
DependencyProperty.RegisterReadOnly(
nameof(EffectiveContentType),
typeof(IconContentType),
typeof(IconElement),
new PropertyMetadata(IconContentType.Material));
/// <summary>
/// 获取当前图标元素实际使用的内容类型。此属性反映了IconElement根据设置的Symbol、Glyph、ImageSource等属性自动确定并使用的具体内容类型。
/// </summary>
public static readonly DependencyProperty EffectiveContentTypeProperty =
EffectiveContentTypePropertyKey.DependencyProperty;
/// <summary>
/// 获取当前图标元素实际使用的内容类型。此属性根据设置的符号、字形等自动确定最合适的IconContentType。
/// </summary>
public IconContentType EffectiveContentType =>
(IconContentType)GetValue(EffectiveContentTypeProperty);
private static readonly DependencyPropertyKey DrawingImagePropertyKey =
DependencyProperty.RegisterReadOnly(
nameof(DrawingImage),
typeof(ImageSource),
typeof(IconElement),
new PropertyMetadata(null));
/// <summary>
/// 用于获取绘制图像的只读属性。此属性表示从Drawing生成的ImageSource。
/// </summary>
public static readonly DependencyProperty DrawingImageProperty =
DrawingImagePropertyKey.DependencyProperty;
/// <summary>
/// 用于获取表示当前绘制内容的ImageSource。此属性是只读的其值基于Drawing属性自动生成。
/// </summary>
public ImageSource? DrawingImage => (ImageSource?)GetValue(DrawingImageProperty);
#endregion
#region
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (IconElement)d;
ctl.UpdateDerived();
ctl.UpdateEffective();
}
private void UpdateDerived()
{
if (Drawing != null)
{
var img = new DrawingImage(Drawing);
if (img.CanFreeze) img.Freeze();
SetValue(DrawingImagePropertyKey, img);
}
else
{
SetValue(DrawingImagePropertyKey, null);
}
}
private void UpdateEffective()
{
IconContentType kind;
if (ContentType == IconContentType.Auto)
{
kind =
ImageSource != null ? IconContentType.Image :
Geometry != null ? IconContentType.Geometry :
DrawingBrush != null ? IconContentType.Brush :
Drawing != null ? IconContentType.Drawing :
!string.IsNullOrEmpty(Glyph) ? IconContentType.Glyph :
IconContentType.Material;
}
else
{
kind = ContentType;
}
SetValue(EffectiveContentTypePropertyKey, kind);
}
/// <summary>
/// 将给定的字符串名称解析为对应的MaterialSymbol枚举值。
/// 如果提供的字符串为空或无法解析则返回默认值MaterialSymbol.CR。
2025-08-20 12:10:35 +08:00
/// </summary>
/// <param name="name">要解析成MaterialSymbol枚举值的字符串。</param>
/// <returns>与给定字符串名称匹配的MaterialSymbol枚举值如果无法找到匹配项或输入无效则返回MaterialSymbol.Cr。</returns>
2025-08-24 13:49:55 +08:00
public static MaterialSymbol Parse(string? name)
2025-08-20 12:10:35 +08:00
{
if (string.IsNullOrEmpty(name))
return MaterialSymbol.CR;
2025-08-20 12:10:35 +08:00
try { return (MaterialSymbol)Enum.Parse(typeof(MaterialSymbol), name); }
catch { return MaterialSymbol.CR; }
2025-08-20 12:10:35 +08:00
}
#endregion
}