功能更新

This commit is contained in:
GG Z
2026-02-12 21:29:00 +08:00
parent a9faf251be
commit b3479d1f39
342 changed files with 4671 additions and 2223 deletions

View File

@@ -0,0 +1,87 @@
using System.ComponentModel;
namespace Melskin.Controls.Decorations;
/// <summary>
/// 装饰基类,用于创建具有特定视觉效果的控件。
/// 该类扩展了ContentControl提供了基础的装饰功能如强度调整和着色器启用。
/// </summary>
/// <remarks>
/// 此类定义了所有装饰控件共享的基本属性和行为。它允许开发者通过设置Intensity强度和ShaderEnabled着色器启用属性来控制装饰效果的表现。
/// 当控件的实际宽度发生变化时会自动更新IsWidthGreaterThanHeight属性以反映当前宽度是否大于高度。
/// </remarks>
public class DecorationBase : ContentControl
{
static DecorationBase()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DecorationBase),
new FrameworkPropertyMetadata(typeof(DecorationBase)));
}
/// <inheritdoc />
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
IsWidthGreaterThanHeight = ActualWidth > ActualHeight;
base.OnRenderSizeChanged(sizeInfo);
}
/// <summary>
/// 着色器效果权重范围0~1
/// </summary>
public double Intensity
{
get => (double)GetValue(IntensityProperty);
set => SetValue(IntensityProperty, value);
}
/// <summary>
/// 启用或禁用边框效果
/// </summary>
public bool ShaderEnabled
{
get => (bool)GetValue(ShaderEnabledProperty);
set => SetValue(ShaderEnabledProperty, value);
}
/// <summary>
/// 指示控件的宽度是否大于其高度。此属性值会根据控件的实际尺寸变化自动更新。
/// </summary>
[ReadOnly(true)]
public bool IsWidthGreaterThanHeight
{
get => (bool)GetValue(IsWidthGreaterThanHeightProperty);
set => SetValue(IsWidthGreaterThanHeightProperty, value);
}
#region Dependency Properties
/// <summary>
/// 代表装饰效果强度的依赖属性其值范围为0到1。默认值设为1.0,表示最大强度。
/// </summary>
public static readonly DependencyProperty IntensityProperty =
DependencyProperty.Register(nameof(Intensity),
typeof(double), typeof(DecorationBase),
new PropertyMetadata(1.0));
/// <summary>
/// 用于控制着色器效果是否启用的依赖属性。默认值为true表示着色器效果是开启状态。
/// </summary>
public static readonly DependencyProperty ShaderEnabledProperty =
DependencyProperty.Register(nameof(ShaderEnabled),
typeof(bool), typeof(DecorationBase),
new PropertyMetadata(true));
/// <summary>
/// 用于标识控件宽度是否大于其高度的依赖属性。此属性值会根据控件的实际尺寸变化自动更新。
/// </summary>
public static readonly DependencyProperty IsWidthGreaterThanHeightProperty =
DependencyProperty.Register(nameof(IsWidthGreaterThanHeight),
typeof(bool), typeof(DecorationBase),
new PropertyMetadata(true));
#endregion
}

View File

@@ -0,0 +1,70 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:cvt="clr-namespace:Melskin.Converters"
xmlns:decorations="clr-namespace:Melskin.Controls.Decorations"
xmlns:internal="clr-namespace:Melskin.Converters.Internal"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type decorations:EmbossBorder}">
<Setter Property="Focusable" Value="False" />
<Setter Property="CornerRadius" Value="4" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderNormalBrush}" />
<Setter Property="Background" Value="{DynamicResource ControlBackgroundNormalBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="4" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Intensity" Value="1" />
<Setter Property="LightShadowBrush" Value="{DynamicResource LightShadowBrush}" />
<Setter Property="DarkShadowBrush" Value="{DynamicResource DarkShadowBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type decorations:EmbossBorder}">
<Grid>
<!-- 光影区域 -->
<!-- 默认4的边距显示光影效果 -->
<Grid Margin="4" Visibility="{TemplateBinding ShaderEnabled, Converter={x:Static cvt:BooleanToVisibilityConverter.CollapsedInstance}}">
<!-- 暗部 -->
<Border
Background="{TemplateBinding DarkShadowBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Intensity,
Converter={x:Static internal:IntensityToEmbossMarginRightBottomConverter.Instance}}"
x:Name="DarkBorder" />
<!-- 亮部 -->
<Border
Background="{TemplateBinding LightShadowBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Intensity,
Converter={x:Static internal:IntensityToEmbossMarginLeftTopConverter.Instance}}" />
<!-- 模糊效果 -->
<Grid.Effect>
<BlurEffect Radius="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Intensity, Converter={x:Static internal:IntensityToEmbossBlurConverter.Instance}, Mode=OneWay}" />
</Grid.Effect>
</Grid>
<!-- 内容区域 -->
<!-- 默认4的边距显示光影效果 -->
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="4"
Padding="{TemplateBinding Padding}">
<ContentPresenter
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
TextElement.Foreground="{TemplateBinding Foreground}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
x:Name="contentPresenter" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,69 @@
namespace Melskin.Controls.Decorations;
/// <summary>
/// 浮雕边框
/// </summary>
public class EmbossBorder : DecorationBase
{
static EmbossBorder()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(EmbossBorder),
new FrameworkPropertyMetadata(typeof(EmbossBorder)));
}
/// <summary>
/// 获取或设置边框圆角的半径。
/// </summary>
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
/// <summary>
/// 高亮部分的画刷
/// </summary>
public SolidColorBrush LightShadowBrush
{
get => (SolidColorBrush)GetValue(LightShadowBrushProperty);
set => SetValue(LightShadowBrushProperty, value);
}
/// <summary>
/// 阴影部分的画刷
/// </summary>
public SolidColorBrush DarkShadowBrush
{
get => (SolidColorBrush)GetValue(DarkShadowBrushProperty);
set => SetValue(DarkShadowBrushProperty, value);
}
#region Dependency Properties
/// <summary>
/// 表示边框圆角半径的依赖属性。
/// </summary>
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(nameof(CornerRadius),
typeof(CornerRadius), typeof(EmbossBorder),
new PropertyMetadata(new CornerRadius(4)));
/// <summary>
/// 获取或设置用于浮雕边框的浅色阴影画刷。
/// </summary>
public static readonly DependencyProperty LightShadowBrushProperty =
DependencyProperty.Register(nameof(LightShadowBrush),
typeof(SolidColorBrush), typeof(EmbossBorder),
new PropertyMetadata(Brushes.WhiteSmoke));
/// <summary>
/// 获取或设置用于浮雕边框的深色阴影画刷。
/// </summary>
public static readonly DependencyProperty DarkShadowBrushProperty =
DependencyProperty.Register(nameof(DarkShadowBrush),
typeof(SolidColorBrush), typeof(EmbossBorder),
new PropertyMetadata(Brushes.DarkGray));
#endregion
}

View File

@@ -0,0 +1,212 @@
using System.Windows.Media.Effects;
namespace Melskin.Controls.Decorations;
/// <summary>
/// GlassChromeDecorator 类用于创建具有玻璃效果的装饰器。该类继承自 Decorator提供了背景、边框画刷、边框厚度、圆角半径以及外部阴影效果等属性以实现现代化且美观的用户界面元素。
/// </summary>
/// <remarks>
/// 通过设置不同的属性值,可以轻松定制具有透明度和柔和边缘的视觉效果,适合用于需要增强视觉吸引力的应用程序窗口或控件装饰。
/// </remarks>
/// <example>
/// <code>
/// xmlns:controls="clr-namespace:Melskin.Controls"
/// <GlassChromeDecorator Width="180" Height="220"
/// HorizontalAlignment="Left" VerticalAlignment="Bottom"
/// Margin="50"
/// CornerRadius="10"
/// Background="#40FF0000">
/// <!-- 半透明红色背景 -->
/// <TextBlock Text = "Mini Card" Foreground="White" FontSize="16"/>
///</GlassChromeDecorator>
/// </code>
/// <![CDATA[]]>
/// </example>
public class GlassChromeDecorator : Decorator
{
// 我们使用依赖属性,这样就可以在 XAML 中设置它们,并支持数据绑定。
#region Dependency Properties
/// <summary>
///
/// </summary>
public static readonly DependencyProperty BackgroundProperty =
DependencyProperty.Register(nameof(Background), typeof(Brush), typeof(GlassChromeDecorator),
new FrameworkPropertyMetadata(new SolidColorBrush(Color.FromArgb(0x26, 0xFF, 0xFF, 0xFF)), FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 表示控件背景的画刷。
/// </summary>
/// <remarks>
/// 该属性定义了GlassChromeDecorator控件的背景颜色和样式。当此属性发生变化时将影响控件的渲染。
/// 默认值为一个具有特定透明度的颜色的SolidColorBrush。
/// </remarks>
public Brush Background
{
get => (Brush)GetValue(BackgroundProperty);
set => SetValue(BackgroundProperty, value);
}
/// <summary>
/// 表示用于绘制边框的画刷的依赖属性。
/// </summary>
/// <remarks>
/// 该属性定义了GlassChromeDecorator控件边框的颜色和样式。当此属性发生变化时将影响控件的渲染。
/// 默认值为一个具有特定颜色透明度的SolidColorBrush。
/// </remarks>
public static readonly DependencyProperty BorderBrushProperty =
DependencyProperty.Register(nameof(BorderBrush), typeof(Brush), typeof(GlassChromeDecorator),
new FrameworkPropertyMetadata(new SolidColorBrush(Color.FromArgb(0x4C, 0xFF, 0xFF, 0xFF)), FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 获取或设置用于绘制边框的画刷。
/// </summary>
/// <remarks>
/// 此属性允许您指定一个画刷,该画刷将用于渲染控件的边框。通过修改此属性,您可以改变边框的颜色、渐变或其他视觉效果。
/// 默认值为半透明的白色ARGB: 0x4CFFFFFF
/// </remarks>
public Brush BorderBrush
{
get => (Brush)GetValue(BorderBrushProperty);
set => SetValue(BorderBrushProperty, value);
}
/// <summary>
/// 表示边框厚度的依赖属性。此属性影响渲染,其默认值为 1。
/// </summary>
public static readonly DependencyProperty BorderThicknessProperty =
DependencyProperty.Register(nameof(BorderThickness), typeof(Thickness), typeof(GlassChromeDecorator),
new FrameworkPropertyMetadata(new Thickness(1), FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
///
/// </summary>
public Thickness BorderThickness
{
get => (Thickness)GetValue(BorderThicknessProperty);
set => SetValue(BorderThicknessProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(nameof(CornerRadius), typeof(CornerRadius), typeof(GlassChromeDecorator),
new FrameworkPropertyMetadata(new CornerRadius(20), FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
///
/// </summary>
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
/// <summary>
/// 表示控件外部阴影效果的属性。
/// </summary>
/// <remarks>
/// 该属性定义了GlassChromeDecorator控件的外部阴影效果。通过设置此属性可以自定义控件的阴影外观如阴影深度、模糊半径和颜色等。默认值为一个具有特定参数的DropShadowEffect实例。
/// 当此属性发生变化时,将影响控件的渲染。
/// </remarks>
public static readonly DependencyProperty OuterShadowEffectProperty =
DependencyProperty.Register(nameof(OuterShadowEffect), typeof(Effect), typeof(GlassChromeDecorator),
new PropertyMetadata(new DropShadowEffect { ShadowDepth = 8, BlurRadius = 32, Color = Color.FromArgb(0x1A, 0, 0, 0) }));
/// <summary>
/// 表示控件外阴影效果。
/// </summary>
/// <remarks>
/// 该属性定义了GlassChromeDecorator控件的外阴影样式。通过设置不同的Effect对象可以改变控件边缘的阴影外观。
/// 默认值为一个具有特定模糊半径、阴影深度和颜色的DropShadowEffect实例。
/// 当此属性发生变化时,将影响控件的整体视觉表现。
/// </remarks>
public Effect OuterShadowEffect
{
get => (Effect)GetValue(OuterShadowEffectProperty);
set => SetValue(OuterShadowEffectProperty, value);
}
#endregion
// 构造函数中应用外阴影
/// <summary>
/// GlassChromeDecorator 类用于创建具有玻璃效果和自定义边框的装饰器。此控件扩展了 WPF 的 Decorator 类,允许用户通过设置属性来自定义背景色、边框颜色、边框厚度、圆角半径以及外阴影效果。
/// </summary>
public GlassChromeDecorator()
{
// 将外阴影效果绑定到控件自身
Effect = OuterShadowEffect;
}
// 关键的 OnRender 方法,所有绘图逻辑都在这里
/// <inheritdoc />
protected override void OnRender(DrawingContext dc)
{
// 确保我们有有效绘制区域
if (RenderSize.Width <= 0 || RenderSize.Height <= 0)
return;
var bounds = new Rect(0, 0, RenderSize.Width, RenderSize.Height);
var pen = new Pen(BorderBrush, BorderThickness.Left);
var cornerRadius = CornerRadius;
// 1. 绘制主背景和边框
dc.DrawRoundedRectangle(Background, pen, bounds, cornerRadius.TopLeft, cornerRadius.TopRight);
// 2. 绘制内部阴影/高光层
var insetShadowBrush = new LinearGradientBrush(
new GradientStopCollection
{
new GradientStop(Color.FromArgb(0x80, 0xFF, 0xFF, 0xFF), 0),
new GradientStop(Colors.Transparent, 0.01),
new GradientStop(Colors.Transparent, 0.99),
new GradientStop(Color.FromArgb(0x1A, 0xFF, 0xFF, 0xFF), 1)
},
new Point(0, 0), new Point(0, 1));
dc.DrawRoundedRectangle(insetShadowBrush, null, bounds, cornerRadius.TopLeft, cornerRadius.TopRight);
// 3. 绘制内部径向辉光
//var innerGlowBrush = new RadialGradientBrush(
// new GradientStopCollection
// {
// new GradientStop(Color.FromArgb(0x99, 0xFF, 0xFF, 0xFF), 0),
// new GradientStop(Colors.Transparent, 1)
// })
//{
// Center = new Point(0.5, 0.5),
// RadiusX = 1.5,
// RadiusY = 1.5
//};
// 将辉光绘制在一个稍小的矩形内
//var glowBounds = new Rect(bounds.X + 10, bounds.Y + 10, bounds.Width - 20, bounds.Height - 20);
//dc.DrawRoundedRectangle(innerGlowBrush, null, glowBounds, cornerRadius.TopLeft, cornerRadius.TopRight);
//// 4. 绘制顶部高光线 (模拟 ::before)
//var topHighlightBrush = new LinearGradientBrush(
// new GradientStopCollection
// {
// new GradientStop(Colors.Transparent, 0),
// new GradientStop(Color.FromArgb(0xCC, 0xFF, 0xFF, 0xFF), 0.5),
// new GradientStop(Colors.Transparent, 1)
// },
// new Point(0, 0.5), new Point(1, 0.5));
//// 绘制一个1像素高的矩形
//dc.DrawRectangle(topHighlightBrush, null, new Rect(bounds.X + 1, bounds.Y + 1, bounds.Width - 2, 1));
//// 5. 绘制左侧高光线 (模拟 ::after)
//var leftHighlightBrush = new LinearGradientBrush(
// new GradientStopCollection
// {
// new GradientStop(Color.FromArgb(0xCC, 0xFF, 0xFF, 0xFF), 0),
// new GradientStop(Colors.Transparent, 0.5),
// new GradientStop(Color.FromArgb(0x4C, 0xFF, 0xFF, 0xFF), 1)
// },
// new Point(0.5, 0), new Point(0.5, 1));
// 绘制一个1像素宽的矩形
//dc.DrawRectangle(leftHighlightBrush, null, new Rect(bounds.X + 1, bounds.Y + 1, 1, bounds.Height - 2));
}
}

View File

@@ -0,0 +1,63 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:decorations="clr-namespace:Melskin.Controls.Decorations"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type decorations:LightedSurface}">
<Setter Property="Focusable" Value="False" />
<Setter Property="LightColorBrush" Value="#FF111319" />
<Setter Property="LightSize" Value="200" />
<Setter Property="Padding" Value="5" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderNormalBrush}" />
<Setter Property="Background" Value="{DynamicResource ControlBackgroundNormalBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type decorations:LightedSurface}">
<ControlTemplate.Resources>
<Storyboard x:Key="ShowLight">
<DoubleAnimation
Duration="0:0:0.2"
Storyboard.TargetProperty="LightIntensity"
To="1" />
</Storyboard>
<Storyboard x:Key="HideLight">
<DoubleAnimation
Duration="0:0:0.2"
Storyboard.TargetProperty="LightIntensity"
To="0" />
</Storyboard>
</ControlTemplate.Resources>
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
x:Name="PART_lightBorder">
<ContentPresenter
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
TextElement.Foreground="{TemplateBinding Foreground}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
x:Name="contentPresenter" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ShowLight}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HideLight}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,188 @@
using System.Windows.Input;
using Melskin.Effects;
namespace Melskin.Controls.Decorations;
/// <summary>
/// LightedSurface 控件继承自 ContentControl用于创建具有光照效果的表面。该控件支持鼠标移动时的动态光照反应
/// 并允许通过设置不同的属性来自定义光照的颜色、强度和大小等特性。
/// </summary>
/// <remarks>
/// 此控件适用于需要在界面上添加视觉吸引力或强调区域的应用场景,比如按钮高亮、列表项选择或其他交互元素。
/// 通过调整光照颜色LightColorBrush、光照强度LightIntensity以及光照大小LightSize等属性
/// 可以实现丰富的视觉效果。此外CornerRadius 属性允许设置控件圆角,从而使得光照效果更加柔和自然。
/// </remarks>
public class LightedSurface : ContentControl
{
static LightedSurface()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LightedSurface),
new FrameworkPropertyMetadata(typeof(LightedSurface)));
}
private readonly LightedSurfaceEffect effect = new();
/// <inheritdoc />
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
InitEffect();
}
private void InitEffect()
{
var contentBorder = GetTemplateChild("PART_lightBorder") as System.Windows.Controls.Border;
effect.UiSize = new Point(ActualWidth, ActualHeight);
effect.LightSize = LightSize;
effect.LightColor = LightColorBrush.Color;
effect.Intensity = LightIntensity;
contentBorder!.Effect = effect;
}
/// <inheritdoc />
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
effect.MousePosition = e.GetPosition(this);
}
/// <inheritdoc />
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
effect.UiSize = new Point(sizeInfo.NewSize.Width, sizeInfo.NewSize.Height);
}
/// <summary>
/// 获取或设置光照的颜色。此属性决定了 LightedSurface 控件上光照效果的颜色。
/// </summary>
/// <remarks>
/// 通过修改此属性,可以改变控件表面光照的颜色,从而实现不同的视觉效果。默认情况下,光照颜色为白色。
/// 若要自定义光照颜色,请设置一个 SolidColorBrush 对象作为此属性的值。
/// </remarks>
public SolidColorBrush LightColorBrush
{
get => (SolidColorBrush)GetValue(LightColorBrushProperty);
set => SetValue(LightColorBrushProperty, value);
}
/// <summary>
/// 定义了 LightedSurface 控件的光照颜色属性。此依赖属性允许用户设置控件的光照颜色,支持使用任何 SolidColorBrush 对象。
/// 当此属性值发生变化时,会触发 LightColorChangedCallback 方法,从而更新控件内部使用的光照效果的颜色。
/// </summary>
public static readonly DependencyProperty LightColorBrushProperty =
DependencyProperty.Register(nameof(LightColorBrush),
typeof(SolidColorBrush), typeof(LightedSurface),
new PropertyMetadata(Brushes.White, LightColorChangedCallback));
/// <summary>
/// 当 LightedSurface 控件的光照颜色属性值发生变化时调用此回调方法。
/// 方法会更新与控件关联的效果中的光照颜色。
/// </summary>
/// <param name="d">触发属性更改的依赖对象,此处应为 LightedSurface 的一个实例。</param>
/// <param name="e">包含有关属性更改的信息,包括新旧值。</param>
private static void LightColorChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not LightedSurface lightedSurface)
{
return;
}
lightedSurface.effect.LightColor = ((SolidColorBrush)e.NewValue).Color;
}
/// <summary>
/// 获取或设置光照的强度。此属性决定了 LightedSurface 控件上光照效果的亮度。
/// </summary>
/// <remarks>
/// 通过修改此属性,可以改变控件表面光照的亮度,从而实现不同的视觉效果。光照强度的有效范围是 0 到 1其中 0 表示无光照1 表示最大亮度。默认情况下,光照强度为 0。
/// </remarks>
public double LightIntensity
{
get => (double)GetValue(LightIntensityProperty);
set => SetValue(LightIntensityProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty LightIntensityProperty =
DependencyProperty.Register(nameof(LightIntensity),
typeof(double), typeof(LightedSurface),
new PropertyMetadata(0.0, LightIntensityChangedCallback));
private static void LightIntensityChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not LightedSurface lightedSurface)
{
return;
}
lightedSurface.effect.Intensity = (double)e.NewValue;
}
/// <summary>
/// 获取或设置光源的大小。此属性决定了 LightedSurface 控件上光照效果的尺寸。
/// </summary>
/// <remarks>
/// 通过修改此属性,可以调整控件表面光照的大小,从而实现不同的视觉效果。默认情况下,光源大小为 40.0。
/// 若要自定义光源大小,请设置一个 double 类型的值作为此属性的值。
/// </remarks>
public double LightSize
{
get => (double)GetValue(LightSizeProperty);
set => SetValue(LightSizeProperty, value);
}
/// <summary>
/// 获取或设置光照的大小。此属性决定了 LightedSurface 控件上光照效果的尺寸。
/// </summary>
/// <remarks>
/// 通过修改此属性,可以改变控件表面光照的大小,从而实现不同的视觉效果。默认情况下,光照大小为 40.0。
/// 若要自定义光照大小,请设置一个 double 类型的值作为此属性的值。
/// 当此属性值发生变化时,会触发 LightSizeChangedCallback 方法,从而更新控件内部使用的光照效果的大小。
/// </remarks>
public static readonly DependencyProperty LightSizeProperty =
DependencyProperty.Register(nameof(LightSize),
typeof(double), typeof(LightedSurface),
new PropertyMetadata(40.0, LightSizeChangedCallback));
private static void LightSizeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not LightedSurface lightedSurface)
{
return;
}
lightedSurface.effect.LightSize = (double)e.NewValue;
}
/// <summary>
/// 获取或设置控件的圆角半径。此属性决定了 LightedSurface 控件四个角的圆角程度。
/// </summary>
/// <remarks>
/// 通过修改此属性可以改变控件边角的圆滑程度从而实现不同的视觉效果。默认情况下圆角半径为4。
/// 若要自定义圆角半径,请设置一个 CornerRadius 对象作为此属性的值。
/// </remarks>
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
/// <summary>
/// 定义了 LightedSurface 控件的圆角属性。此依赖属性允许用户设置控件四个角的半径,从而改变控件外观的圆润程度。
/// 通过修改此属性,可以使得光照效果更加柔和自然,适用于需要平滑边缘的应用场景。
/// </summary>
/// <remarks>
/// 默认情况下CornerRadius 的值为 4。用户可以通过设置不同的 CornerRadius 值来自定义控件的圆角大小。
/// 例如,设置更大的 CornerRadius 可以使控件看起来更圆润,而较小的值则会使控件的边缘更加锐利。
/// </remarks>
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(nameof(CornerRadius),
typeof(CornerRadius), typeof(LightedSurface),
new PropertyMetadata(new CornerRadius(4)));
}

View File

@@ -0,0 +1,101 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:conv="clr-namespace:Melskin.Converters"
xmlns:dec="clr-namespace:Melskin.Controls.Decorations"
xmlns:internal="clr-namespace:Melskin.Converters.Internal"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type dec:SlotBorder}">
<Setter Property="Focusable" Value="False" />
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="Background" Value="{DynamicResource ControlBackgroundNormalBrush}" />
<Setter Property="LightShadowBrush" Value="{DynamicResource LightShadowBrush}" />
<Setter Property="DarkShadowBrush" Value="{DynamicResource DarkShadowBrush}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="CornerRadius" Value="4" />
<Setter Property="Padding" Value="2" />
<Setter Property="ShaderEnabled" Value="True" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Intensity" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type dec:SlotBorder}">
<Grid>
<!-- 隐藏阴影的时候呈现背景色 -->
<!-- 默认4的边距显示光影效果 -->
<Border
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="4" />
<!-- 内阴影效果 -->
<Grid Visibility="{TemplateBinding ShaderEnabled, Converter={x:Static conv:BooleanToVisibilityConverter.CollapsedInstance}}">
<!-- 背景填充 -->
<Rectangle Fill="{TemplateBinding Background}" />
<!-- 左上阴影 -->
<Border
Background="{TemplateBinding DarkShadowBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Intensity,
Converter={x:Static internal:IntensityToSlotShadowMarginConverter.Instance}}" />
<!-- 右下高亮 -->
<Border
Background="{TemplateBinding LightShadowBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Intensity,
Converter={x:Static internal:IntensityToSlotLightMarginConverter.Instance}}" />
<!-- 背景中央 -->
<Border
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="{TemplateBinding Intensity,
Converter={x:Static internal:IntensityToSlotMarginConverter.Instance}}" />
<!-- 裁切区域 -->
<Grid.Clip>
<MultiBinding
Converter="{x:Static internal:CreateSlotClipGeometryConverter.Instance}"
ConverterParameter="4"
Mode="OneWay">
<Binding
Mode="OneWay"
Path="CornerRadius"
RelativeSource="{RelativeSource TemplatedParent}" />
<Binding
Mode="OneWay"
Path="ActualWidth"
RelativeSource="{RelativeSource TemplatedParent}" />
<Binding
Mode="OneWay"
Path="ActualHeight"
RelativeSource="{RelativeSource TemplatedParent}" />
</MultiBinding>
</Grid.Clip>
<Grid.Effect>
<BlurEffect Radius="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Intensity, Converter={x:Static internal:IntensityToSlotBlurConverter.Instance}, Mode=OneWay}" />
</Grid.Effect>
</Grid>
<!-- 显示边框和内容 -->
<!-- 默认4的边距显示光影效果 -->
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="4">
<ContentPresenter
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
TextElement.Foreground="{TemplateBinding Foreground}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
x:Name="contentPresenter" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,70 @@
namespace Melskin.Controls.Decorations;
/// <summary>
/// SlotBorder 类继承自 DecorationBase用于为控件添加具有圆角和阴影效果的装饰边框。
/// 通过设置 CornerRadius 属性可以控制边框的圆角程度,同时 LightShadowBrush 和 DarkShadowBrush 属性允许用户自定义浅色和深色阴影的颜色。
/// </summary>
public class SlotBorder : DecorationBase
{
static SlotBorder()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(SlotBorder),
new FrameworkPropertyMetadata(typeof(SlotBorder)));
}
/// <summary>
/// 获取或设置边框的圆角半径。
/// </summary>
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
/// <summary>
/// 高亮笔刷
/// </summary>
public SolidColorBrush LightShadowBrush
{
get => (SolidColorBrush)GetValue(LightShadowBrushProperty);
set => SetValue(LightShadowBrushProperty, value);
}
/// <summary>
/// 阴影笔刷
/// </summary>
public SolidColorBrush DarkShadowBrush
{
get => (SolidColorBrush)GetValue(DarkShadowBrushProperty);
set => SetValue(DarkShadowBrushProperty, value);
}
#region Dependency Properties
/// <summary>
/// 用于定义边角半径的依赖属性,控制装饰控件的圆角程度。
/// </summary>
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(nameof(CornerRadius),
typeof(CornerRadius), typeof(SlotBorder),
new PropertyMetadata(new CornerRadius(4)));
/// <summary>
/// 浅色阴影笔刷
/// </summary>
public static readonly DependencyProperty LightShadowBrushProperty =
DependencyProperty.Register(nameof(LightShadowBrush),
typeof(SolidColorBrush), typeof(SlotBorder),
new PropertyMetadata(Brushes.WhiteSmoke));
/// <summary>
/// 深色阴影笔刷
/// </summary>
public static readonly DependencyProperty DarkShadowBrushProperty =
DependencyProperty.Register(nameof(DarkShadowBrush),
typeof(SolidColorBrush), typeof(SlotBorder),
new PropertyMetadata(Brushes.DarkGray));
#endregion
}