Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >[WPF] 玩玩彩虹文字及动画

[WPF] 玩玩彩虹文字及动画

作者头像
dino.c
发布于 2021-11-10 07:05:13
发布于 2021-11-10 07:05:13
83400
代码可运行
举报
文章被收录于专栏:dino.c的专栏dino.c的专栏
运行总次数:0
代码可运行

1. 前言

兴致来了玩玩 WPF 的彩虹文字。不是用 LinearGradientBrush 制作渐变色那种,是指每个文字独立颜色那种彩虹文字。虽然没什么实用价值,但希望这篇文章里用 ItemsControl 拆分文字,以及用工具类提供递增和随机变量的做法可以给读者一些启发,就好了。

2. 用 TextBlock 的 Run

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<TextBlock>
    <Run Foreground="#4a0e68">b</Run>
    <Run Foreground="#b62223">l</Run>
    <Run Foreground="#fdd70c">o</Run>
    <Run Foreground="#f16704">c</Run>
    <Run Foreground="#69982d">k</Run>
    <Run Foreground="#0075a5">.</Run>
    <Run Foreground="#0b0045">R</Run>
    <Run Foreground="#4a0e68">u</Run>
    <Run Foreground="#b62223">n</Run>
</TextBlock>

用 TextBlock 的 Run 是做基本的做法,还有其它各种给 TextBlock 设置格式的方法,具体可以参考 text-block#formatting-text 这篇文档。

3. 写代码

这种方案就是用代码将字符串拆分,然后逐个字符塞进 TextBlock 然后放进 StackPanel,实现方式很无趣,我就不写了。

4. 用 ItemsControl

第三种方案是用 ItemsControl 实现,这个方案虽然会绕些弯路,但胜在够有趣,而且能扩展其它玩法。

首先,因为 string 是个集合,其实它可以用作 ItemsControl 的 ItemsSource。但在 Xaml 上直接写 ItemsSource="somestring"` 会报错,可以用 ContentControl 包装一下,写成这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ContentControl Content="ItemsControl" >
    <ContentControl.Template>
        <ControlTemplate TargetType="ContentControl">
            <ItemsControl ItemsSource="{TemplateBinding Content}" >
            </ItemsControl>
        </ControlTemplate>
    </ContentControl.Template>
</ContentControl>

然后设置 ItemsControl 的 ItemsPanel,让内容横向排列;设置 DataTemplate,让拆分后的字符显示在 TextBlock 上:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ItemsControl ItemsSource="{TemplateBinding Content}" >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

接下来,为了让每个字符显示不同的颜色,需要实现一个 Collection 类并在 Xaml 上实例化它,将用到的颜色放进去:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<common:RepeatCollection x:Key="RepeatCollection">
    <SolidColorBrush>#4a0e68</SolidColorBrush>
    <SolidColorBrush>#b62223</SolidColorBrush>
    <SolidColorBrush>#fdd70c</SolidColorBrush>
    <SolidColorBrush>#f16704</SolidColorBrush>
    <SolidColorBrush>#69982d</SolidColorBrush>
    <SolidColorBrush>#0075a5</SolidColorBrush>
    <SolidColorBrush>#0b0045</SolidColorBrush>
</common:RepeatCollection>

这个 RepeatCollection 的代码如下,它其实是个循环队列,每次调用 Next 的 getter 方法就拿下一个元素(叫 CircleCollection 会不会好些?):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class RepeatCollection : Collection<object>
{
    private int _offset;

    public object Next
    {
        get
        {
            if (this.Count == 0)
                return null;

            var result = this[_offset];
            _offset++;
            if (_offset > this.Count - 1)
                _offset = 0;

            return result;
        }
    }
}

最后,TextBlock 的 Foreground 绑定到集合的 Next 属性,实现每一个 TextBlock 都使用不同的颜色:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<TextBlock Foreground="{Binding Next, Source={StaticResource RepeatCollection}}" Text="{Binding}" />

5. 动画

从第三种方案延申,我试玩了几种动画。

首先我写了个 TimeSpanIncreaser 类,它包含 Start、Setp、Next 三个属性,其中 Next 的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public override TimeSpan Next => Start + (_current += Step);

它的作用就是每次调用 Next 属性,这个属性返回的值都递增。

回到 Xaml,首先在 Resources 中定义一个实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<common:TimeSpanIncreaser x:Key="TimeSpanIncreaser" Step="0:0:0.2" />

然后在 TextBlock 里加上这段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<TextBlock.RenderTransform>
    <TranslateTransform Y="-90" />
</TextBlock.RenderTransform>
<FrameworkElement.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation BeginTime="{Binding Next, Source={StaticResource TimeSpanIncreaser}}"
                                 Storyboard.TargetName="TextElement"
                                 Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
                                 To="0"
                                 Duration="0:0:0.7">
                    <DoubleAnimation.EasingFunction>
                        <BounceEase EasingMode="EaseOut" />
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</FrameworkElement.Triggers>

每个 TextBlock 使用相同的动画,但动画的开始时间是逐个递增的,运行起来效果如下:

再大胆些,ItemsControl 嵌套 ItemsControl,就可以做出下面这种效果:

又或者,这次不玩递增,玩随机。首先实现这两个类然后实例化,代码我就不贴出来了,看名字就能懂它们实现了什么功能:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<common:RandomColorCreator x:Key="RandomColorCreator" />
<common:RandomDoubleCreator x:Key="RandomDoubleCreator" Max="20" />

然后让 TextBlock 的 Foreground 和 TranslateTransform 动画的 X、Y 绑定到这两个实例的 Next 属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<TextBlock.Foreground>
    <SolidColorBrush Color="{Binding Next, Source={StaticResource RandomColorCreator}}" />
</TextBlock.Foreground>
<TextBlock.RenderTransform>
    <TranslateTransform />
</TextBlock.RenderTransform>
<FrameworkElement.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation AutoReverse="True"
                                 RepeatBehavior="Forever"
                                 Storyboard.TargetName="TextElement"
                                 Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                 To="{Binding Next, Source={StaticResource RandomDoubleCreator}}"
                                 Duration="0:0:.08" />
                <DoubleAnimation AutoReverse="True"
                                 RepeatBehavior="Forever"
                                 Storyboard.TargetName="TextElement"
                                 Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
                                 To="{Binding Next, Source={StaticResource RandomDoubleCreator}}"
                                 Duration="0:0:.1" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</FrameworkElement.Triggers>

又一个毫无实用价值的动画诞生了:

6. 最后

虽然很遗憾没什么用,我只能安慰自己“结果不重要,最重要是享受过程”。

7. 源码

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WPF 修改CheckBox样式
它包含一个复选框(ToggleButton)和一个文(Content),改写它,要做的就是修改它们的模板了~
zls365
2021/04/02
2.7K0
有几十个WPF设计和动画的项目
这是一个 WPF 项目,用于创作及收集一些好玩的设计和动画。目前已有数十个 Demo,部分 Demo 有相关博客介绍详细的实现步骤和原理:
沙漠尽头的狼
2022/04/18
1.3K0
有几十个WPF设计和动画的项目
[WPF] 实现两个任天堂 Switch 的加载动画
写了两个 Switch 的加载动画,第一个是 Swtich 最常见那个 Loading 动画:
dino.c
2021/12/10
6090
[WPF] 实现两个任天堂 Switch 的加载动画
代码创建 WPF 旋转、翻转动画(汇总)
先建立一个button <Button Width="80" Height="60" Content="旋转" Name="trans" Click="trans_Click" Style="{x:Null}"/> 方法一:绕左上角旋转 public void Transform1() { RotateTransform rtf = new RotateTransform(); trans.RenderTransform
hbbliyong
2018/03/05
3.5K0
代码创建 WPF 旋转、翻转动画(汇总)
WPF中触发器Trigger、MultiTrigger、DataTrigger、MultiDataTrigger
WPF中有种叫做触发器的东西(记住不是数据库的trigger哦)。它的主要作用是根据trigger的不同条件来自动更改外观属性,或者执行动画等操作。
zls365
2021/01/28
3.4K0
Silverlight之ListBox/Style学习笔记--ListBox版的图片轮换广告
ListBox是一个很有用的控件,其功能直逼Asp.Net中的Repeater,它能实现自定义数据项模板,纵向/横向排列Item(如果扩展一下实现自行折行,几乎就是SL版的Repeater了--实际上WrapPanel已经实现了,不过没有默认集成在SL3中).  这里推荐一个老外的文章 http://blogs.msdn.com/delay/archive/2008/03/05/lb-sv-faq-examples-notes-tips-and-more-for-silverlight-2-beta-1-s
菩提树下的杨过
2018/01/22
1K0
Silverlight之ListBox/Style学习笔记--ListBox版的图片轮换广告
win10 uwp 修改Pivot Header 颜色
参见: http://stackoverflow.com/questions/31797875/overriding-pivot-header-foreground-brushes-in-uwp-app-win-10-rtm-sdk
林德熙
2018/09/19
6580
win10 uwp 修改Pivot Header 颜色
WPF TreeGrid MVVM 模式下自定义表格带展开缩放效果,并且可以获取点击行的数据
MVVM其实就是:Model 、View、ViewModel三个的简称,就像MVC一样。 Model就是模型。View就是视图。ViewModel就是和view进行绑定的。
Shunnet
2022/05/31
6K0
WPF TreeGrid MVVM 模式下自定义表格带展开缩放效果,并且可以获取点击行的数据
win10 UWP 圆形等待
使用 RectangleStyle1 在 Rectangle 使用 style="{StaticResource RectangleStyle1}"
林德熙
2018/09/18
4100
win10 UWP 圆形等待
[WPF 自定义控件]自定义一个“传统”的 Validation.ErrorTemplate
数据绑定模型允许您将与您Binding的对象相关联ValidationRules。 如果用户输入的值无效,你可能希望在应用程序 用户界面 (UI) 上提供一些有关错误的反馈。 提供此类反馈的一种方法是设置Validation.ErrorTemplate附加到自定义ControlTemplate的属性。
dino.c
2020/03/02
1.5K0
Silverlight的自定义tooltip提示工具条
这种应用场景其实很多,比如游戏中装备/魔法的选择菜单,这里借用了"深蓝色右手"的一张图  再比如聊天室中的文本颜色设置  虽然sl的ToolTipService.ToolTip属性可以设置任何对象,比
菩提树下的杨过
2018/01/23
1.3K0
Silverlight的自定义tooltip提示工具条
WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None"、AllowsTransparency="True" 这两个属性。如果不想自定义窗口样式,还需要设置 Background="Transparent"。这样的设置会让窗口变成 Layered Window,WPF 在这种类型窗口上的渲染性能是非常糟糕的。
walterlv
2023/10/22
1.8K0
WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
[UWP]理解及扩展Expander
最近在自定义Expander的样式,顺便看了看它的源码。 Expander控件是一个ContentControl,它通过IsExpanded属性或者通过点击Header中的ToggleButton控制内容展开或隐藏。UWP SDK中没提供这个控件,而是在UWP Community Toolkit中 提供 。它是个教科书式的入门级控件,代码简单,虽然仍然不尽如人意,但很适合用于学习如何自定义模版化控件。
dino.c
2019/01/18
8710
[UWP]理解及扩展Expander
WPF 和 UWP 中,不用设置 From 或 To,Storyboard 即拥有更灵活的动画控制
发布于 2017-10-26 04:55 更新于 2018-02-19 22:41
walterlv
2018/09/18
1.2K0
WPF 和 UWP 中,不用设置 From 或 To,Storyboard 即拥有更灵活的动画控制
WPF加载中实现
加载页面 XAML <Window x:Class="SchoolClient.Wins.LoadDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="100" Height="100" AllowsTransparency="True"
码客说
2020/07/27
9680
[Silverlight]用ListBox实现SlideShow
用Silverlight2整整一年了,上个星期公司全面转去Silverlight3,作为纪念就把用SL2写的最后一个东西发出来吧。效果如下:
dino.c
2019/01/18
5960
[Silverlight]用ListBox实现SlideShow
WPF 修改 ItemContainerStyle 鼠标移动到未选中项效果和选中项背景
本文告诉大家如何通过修改 ItemContainerStyle 让 ListView 或 ListBox 的选择效果如鼠标移动到未选中项的效果或选择项的背景
林德熙
2019/03/13
2.4K0
WPF 修改 ItemContainerStyle 鼠标移动到未选中项效果和选中项背景
WPF 制作 Windows 屏保
[1]GitHub: https://github.com/yanjinhuagood/ScreenSaver
独立观察员
2022/12/06
9480
WPF 制作 Windows 屏保
[UWP]用Shape做动画
相对于WPF/Silverlight,UWP的动画系统可以说有大幅提高,不过本文无意深入讨论这些动画API,本文将介绍使用Shape做一些进度、等待方面的动画,除此之外也会介绍一些相关技巧。
dino.c
2019/01/18
2K0
[UWP]用Shape做动画
sliverlight:按点击移动的连续跑马灯
演示效果如下: 鼠标点击一次,所有方块向左移动一格 思路: 1.利用StoryBoard产生移动,每次点击时,该动画播放一次(即移动一格) 2.关键:动画播放完毕后,调用Stop方法,以回到初始位置,
菩提树下的杨过
2018/01/23
7710
sliverlight:按点击移动的连续跑马灯
推荐阅读
相关推荐
WPF 修改CheckBox样式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验