首页 > 其他分享 >来瞧瞧,WPF 炫酷走马灯!

来瞧瞧,WPF 炫酷走马灯!

时间:2022-08-22 10:33:37浏览次数:76  
标签:textBlockTop public TextBlock 炫酷 typeof 走马灯 new WPF SpotLight

来瞧瞧,WPF 炫酷走马灯!

控件名:SpotLight

作者:WPFDevelopersOrg

原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers

  • 框架使用大于等于.NET40

  • Visual Studio 2022;

  • 项目使用 MIT 开源许可协议;

  • Canvas做容器方便针对文本TextBlock做裁剪Clip动画操作;

  • Canvas内部创建两个TextBlock

  • 第一个做为背景字体设置字体颜色为浅灰Foreground="#323232",也可以通过依赖属性设置DefaultForeground

  • 第二个字体设置会彩虹色当聚光灯走到某个区域后并显示;

  • Duration可设置动画的从左到右的时长,默认3秒;

  • 根据字体的实际宽度ActualWidth做动画展示从左到右并循环Forever播放;

1)SpotLight.cs 代码如下;

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace WPFDevelopers.Controls
{
    [TemplatePart(Name = TextBlockBottomTemplateName, Type = typeof(TextBlock))]
    [TemplatePart(Name = TextBlockTopTemplateName, Type = typeof(TextBlock))]
    [TemplatePart(Name = EllipseGeometryTemplateName, Type = typeof(EllipseGeometry))]
    public class SpotLight : Control
    {
        private const string TextBlockBottomTemplateName = "PART_TextBlockBottom";
        private const string TextBlockTopTemplateName = "PART_TextBlockTop";
        private const string EllipseGeometryTemplateName = "PART_EllipseGeometry";

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(SpotLight),
                new PropertyMetadata("WPFDevelopers"));

        public static readonly DependencyProperty DefaultForegroundProperty =
            DependencyProperty.Register("DefaultForeground", typeof(Brush), typeof(SpotLight),
                new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#323232"))));


        public static readonly DependencyProperty DurationProperty =
            DependencyProperty.Register("Duration", typeof(TimeSpan), typeof(SpotLight),
                new PropertyMetadata(TimeSpan.FromSeconds(3)));


        private EllipseGeometry _ellipseGeometry;
        private TextBlock _textBlockBottom, _textBlockTop;

        static SpotLight()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SpotLight),
                new FrameworkPropertyMetadata(typeof(SpotLight)));
        }

       
        public TimeSpan Duration
        {
            get => (TimeSpan)GetValue(DurationProperty);
            set => SetValue(DurationProperty, value);
        }
        public Brush DefaultForeground
        {
            get => (Brush)GetValue(DefaultForegroundProperty);
            set => SetValue(DefaultForegroundProperty, value);
        }

        public string Text
        {
            get => (string)GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }
        
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _textBlockBottom = GetTemplateChild(TextBlockBottomTemplateName) as TextBlock;
            _textBlockTop = GetTemplateChild(TextBlockTopTemplateName) as TextBlock;

            _ellipseGeometry = GetTemplateChild(EllipseGeometryTemplateName) as EllipseGeometry;
            var center = new Point(FontSize / 2, FontSize / 2);
            _ellipseGeometry.RadiusX = FontSize;
            _ellipseGeometry.RadiusY = FontSize;
            _ellipseGeometry.Center = center;
            if (_textBlockBottom != null && _textBlockTop != null && _ellipseGeometry != null)
                _textBlockTop.Loaded += _textBlockTop_Loaded;
        }


        private void _textBlockTop_Loaded(object sender, RoutedEventArgs e)
        {
            var doubleAnimation = new DoubleAnimation
            {
                From = 0,
                To = _textBlockTop.ActualWidth,
                Duration = Duration
            };

            Storyboard.SetTarget(doubleAnimation, _textBlockTop);
            Storyboard.SetTargetProperty(doubleAnimation,
                new PropertyPath("(UIElement.Clip).(EllipseGeometry.Transform).(TranslateTransform.X)"));
            var storyboard = new Storyboard
            {
                RepeatBehavior = RepeatBehavior.Forever,
                AutoReverse = true
            };
            storyboard.Children.Add(doubleAnimation);
            storyboard.Begin();
        }
    }
}

2)SpotLight.xaml 代码如下;

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:WPFDevelopers.Controls">
    
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <LinearGradientBrush x:Key="RainbowBrush" EndPoint="1,1" MappingMode="RelativeToBoundingBox" StartPoint="0,0">
        <GradientStop Color="#FF9C1031" Offset="0.1"/>
        <GradientStop Color="#FFBE0E20" Offset="0.2"/>
        <GradientStop Color="#FF9C12AC" Offset="0.7"/>
        <GradientStop Color="#FF0A8DC3" Offset="0.8"/>
        <GradientStop Color="#FF1AEBCC" Offset="1"/>
    </LinearGradientBrush>
    <Style TargetType="{x:Type controls:SpotLight}" BasedOn="{StaticResource ControlBasicStyle}">
        <Setter Property="Background" Value="#222222"/>
        <Setter Property="FontSize" Value="60"/>
        <Setter Property="FontFamily" Value="Arial Black"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Foreground" Value="{StaticResource RainbowBrush}"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:SpotLight}">
                    <Grid x:Name="PART_Canvas" Background="{TemplateBinding Background}">
                        <TextBlock x:Name="PART_TextBlockBottom" Text="{TemplateBinding Text}"
                                   FontSize="{TemplateBinding FontSize}" 
                                   FontFamily="{TemplateBinding FontFamily}"
                                   FontWeight="{TemplateBinding FontWeight}" 
                                   Foreground="{TemplateBinding DefaultForeground}"/>
                        <TextBlock x:Name="PART_TextBlockTop" Text="{TemplateBinding Text}"
                                   FontSize="{TemplateBinding FontSize}"
                                   FontFamily="{TemplateBinding FontFamily}"
                                   FontWeight="{TemplateBinding FontWeight}"
                                   Foreground="{TemplateBinding Foreground}">
                            <TextBlock.Clip>
                                <EllipseGeometry x:Name="PART_EllipseGeometry">
                                    <EllipseGeometry.Transform>
                                        <TranslateTransform/>
                                    </EllipseGeometry.Transform>
                                </EllipseGeometry>
                            </TextBlock.Clip>
                        </TextBlock>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

3)SpotLightExample.xaml代码如下如何使用

<UniformGrid Rows="2" Background="#222222">
        <wpfdev:SpotLight FontSize="50" Text="YanJinHua" 
                          DefaultForeground="Crimson" 
                          Foreground="Fuchsia" 
                          Duration="00:00:05" />
        <wpfdev:SpotLight/>
</UniformGrid>

SpotLight.cs|Github
SpotLight.cs|码云
SpotLight.xaml|Github
SpotLight.xaml|码云

标签:textBlockTop,public,TextBlock,炫酷,typeof,走马灯,new,WPF,SpotLight
From: https://www.cnblogs.com/yanjinhua/p/16611967.html

相关文章

  • WPF实现一个简单自定义管道
    先看效果  xaml代码<UserControlx:Class="WPF控件测试.Control.Pipeline"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"......
  • 《深入浅出WPF》MVVM视频教材中的实例练习
    前言在学习了《深入浅出WPF》的书籍以及视频之后,将最后的MVVM练习项目从头到尾敲了一遍,以加深自己的理解,也是为了提高自己对基础知识的熟练程度。由于是自己对着示例图自......
  • WPF中向下拉框中绑定枚举体
    1、枚举绑定combox的ItemsSourceItemsSource绑定的是个集合值,要想枚举绑定ItemsSource,首先应该想到的是把枚举值变成集合。方法一:使用资源里的ObjectDataProvider如以下枚......
  • WPFGroupBox控件自定义
    先上效果图  直接上代码(直接在Window.Resources里面添加这段代码)<StyleTargetType="GroupBox"><SetterProperty="Margin"Value="10,5"/>......
  • WPF将控件转为图片(Visual试图转Bitmap)
    RenderTargetBitmaptarget=newRenderTargetBitmap((int)grid.ActualWidth,(int)grid.ActualHeight,96d,96d,PixelFormats.Default);target.Render(grid);Cropped......
  • 【WPF】命令系统
    命令四要素1、命令,一般情况都是使用”路由ui命令“2、命令源:触发命令的地方。3、命令绑定:将命令和执行方法绑定,然后在将commandbing放置在,命令目标的外围ui控件上,这样......
  • C# WPF 访问剪切板报错
    如果剪贴板操作失败(例如 HRESULT0x800401D0(CLIPBRD_E_CANT_OPEN) 错误),则会引发相应的 ExternalException (,这是一种ExternalException)。由于Win32 OpenClipbo......
  • C#-WPF-LiveChart大数据时图标绘制(曲线图)并支持图片保存
    xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"<Button   Name="SaveBtn"   Grid.Row="0"   Width="100"   Height="32"   ......
  • 【WPF】XDG0062 必须使“Setter.Property”具有非 null 值。
    编译环境vs2022.net6.0在样式中给附加属性设置触发条件。显示XDG0062错误,但是代码能正常编译和运行。   编辑环境中运行后,能正常运行   解决方法......
  • XAML、WPF 学习笔记
    容器学习:所有的WPF布局容器都派生自System.Windows.Controls.Panel。Panel继承自FrameworkElement。在Panel中有一个比较重要的属性是UIElementCollection类型的Chi......