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