せっかくWPFを利用するなら、Windowsフォームでは作りにくいアニメーションを取り入れたいですよね。
今回は、「Label(or TextBlock)を点滅させる」という要件を実装したいと思います。
実開発で「〇〇処理中」などの文字列をぴょこぴょこさせたい機会があったので備忘録。
アニメーションの動作をStyleで定義するため、リソースディクショナリを作成します。
①ソリューションエクスプローラーでプロジェクトを右クリック
↓
②「追加」⇒「新しい項目」を選択
↓
③「リソースディクショナリ(WPF)」を選択し、任意の名前に変更し、「追加」を選択
(ここではstyle.xamlとします)
追加したstyle.xamlが {プロジェクトルート}\ 下にできたと思います。
中身を下記のように定義します。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<!-- 点滅アニメーション定義 -->
<Storyboard x:Key="FlashStory">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" RepeatBehavior="Forever" AutoReverse="True">
<LinearDoubleKeyFrame KeyTime="0:0:0.2" Value="1" />
<LinearDoubleKeyFrame KeyTime="0:0:0.8" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<!-- Labelスタイル定義 -->
<Style TargetType="Label" x:Key="LabelFlash">
<Style.Triggers>
<EventTrigger RoutedEvent="Label.Loaded">
<BeginStoryboard Storyboard="{StaticResource FlashStory}" />
</EventTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
ソリューションエクスプローラーでstyle.xamlのプロパティを表示し、ビルドアクションを変更します。
なし
↓
Resource
これでソース上でstyle.xamlにアクセスできます。
上記でアクセスできるようにしたstyle.xamlを、アプリケーションに読み込ませます。
{プロジェクトルート}\App.xaml をビューデザイナーで編集します。
Application.Resourcesタグの間に、下記記述を追加します。
<ResourceDictionary Source="style.xaml" />
波線が出るようだとファイルを見つけられていないので、パスを再確認してください。
するとこんな感じ。
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="FlashExample.xaml">
<Application.Resources>
<ResourceDictionary Source="style.xaml" />
</Application.Resources>
</Application>
では実際に使うUIにコントロールを配置します。
<Label x:Name="lblMessage" Content="処理中" Foreground="White" FontSize="22" Background="LightBlue" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Height="40" Style="{StaticResource LabelFlash}" />
大事なところは、↓の部分。
Style="{StaticResource LabelFlash}"
style.xamlに定義したLabel用のアニメーションをスタイルに設定します。
全体ではこんな感じ。
<Window x:Class="WpfApplication1.FlashExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FlashExample" Height="250" Width="325">
<Grid>
<Label x:Name="lblMessage" Content="処理中" Foreground="White" FontSize="22" Background="LightBlue" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Height="40" Style="{StaticResource LabelFlash}" />
</Grid>
</Window>
点滅してくれました。
上記サンプルはラベルで実現しましが、TextBlockの場合はstyle.xamlのTargetTypeとRoutedEventを変更すれば実現できます。
こんなイメージ↓
<!-- TextBlockスタイル定義 -->
<Style TargetType="TextBlock" x:Key="TextBlockFlash">
<Style.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard Storyboard="{StaticResource FlashStory}" />
</EventTrigger>
</Style.Triggers>
</Style>
サンプルでは、RoutedEvent=”Label.Loaded”としているため、
読み込んだら常に点滅のスタイルが適用されます。
実際の要件では、トリガーや条件によって適用することもあると思いますので、例を掲示します。
例)ラベルの背景色変更時に点滅
①ソース側のプロパティを使用するため、XAMLのヘッダーに↓を追記します。
DataContext="{Binding RelativeSource={RelativeSource Self}}"
②Labelの背景色部分を変更します。
Background="LightBlue"
↓
Background="{Binding LblMessageBackground, NotifyOnTargetUpdated=True}"
③ソース側でXAMLのプロパティ(LblMessageBackground)の記述を追加します。
※プロパティの変更を検知するには、INotifyPropertyChangedを実装する必要があります。
using System.Windows;
using System.Windows.Media;
using System.ComponentModel;
namespace WpfApplication1
{
public partial class FlashExample : INotifyPropertyChanged
{
public FlashExample()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
private Brush _lblMessageBackground;
public Brush LblMessageBackground
{
get
{
return _lblMessageBackground;
}
set
{
_lblMessageBackground = value;
OnPropertyChanged("LblMessageBackground");
}
}
protected virtual void OnPropertyChanged(string name)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
LblMessageBackground = new SolidColorBrush(Colors.Red);
}
}
}
One thought on “【WPF】LabelやTextBlockの文字列を点滅させる方法”