Files
Shrlalgo.RvKits/Melskin/Controls/IconElement.xaml.cs
2026-02-17 22:17:13 +08:00

363 lines
14 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 Melskin.Assets;
namespace Melskin.Controls;
/// <summary>
/// 图标控件:支持 MaterialSymbol / Glyph / ImageSource / Geometry / Drawing / DrawingBrush。
/// 使用 DataTemplate 按需创建视觉树,属性变化即时切换模板。
/// </summary>
/// <example>
/// <code lang="xaml">
/// <!-- MaterialSymbol -->
///<IconElement Symbol = "Search" FontSize="20"/>
///<!-- Glyph -->
///<IconElement ContentType = "Glyph"
/// FontFamily="pack://application:,,,/YourAsm;component/Assets/Fonts/#YourFont"
/// Glyph="&#xE001;" FontSize="20"/>
///<!-- Image -->
///<IconElement ImageSource = "/Melskin;component/Assets/Images/add.png" Width="24" Height="24"/>
///<!-- Geometry -->
///<IconElement Geometry = "M0,0 L10,0 10,10 0,10Z"
/// GeometryFill="DodgerBlue"
/// Width="16" Height="16"/>
///<!-- Drawing(代码设置 Drawing) -->
///<IconElement Width="24" Height="24"/>
///<!-- DrawingBrush -->
///<IconElement DrawingBrush = "{StaticResource SomeDrawingBrush}" Width="24" Height="24"/>
/// </code>
/// </example>
public class IconElement : Control
{
static IconElement()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(IconElement),
new FrameworkPropertyMetadata(typeof(IconElement)));
}
/// <summary>
/// 用于显示图标的控件。可以通过设置属性来指定图标的具体样式和内容。
/// </summary>
public IconElement()
{
}
#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));
/// <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>
/// 获取或设置图标元素的字形代码。此属性定义了IconElement将显示的具体字形通常用于指定字体图标。
/// </summary>
public string? Glyph
{
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。
/// </summary>
/// <param name="name">要解析成MaterialSymbol枚举值的字符串。</param>
/// <returns>与给定字符串名称匹配的MaterialSymbol枚举值如果无法找到匹配项或输入无效则返回MaterialSymbol.Cr。</returns>
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
}