質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

2552閲覧

[WPF]コードビハインドの条件を満たしたときだけアニメーションを再生する方法

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2020/10/19 08:41

編集2020/10/20 06:02

###やりたいこと
WPFでアニメーションをつける方法を調べています。
Blendを使えばボタンのクリックなどをトリガーとしてStoryBoardに記述したアニメーションを再生することは簡単にできそうです。
しかし、XAMLに記述したボタンのクリック等のトリガーではなく、コードビハインドで定義しているフラグや条件をトリガーとしてアニメーションを再生するかどうかを決定する方法はありますか?

例として、下のようなサンプルプログラムを作ってみました。
「朝」「昼」「夜」のボタンを押すとコードビハインドで変数nowがそれぞれに対応した値を持ちます。
その後、「あいさつ」ボタンをクリックすると時間帯に対応したあいさつの言葉がテキストブロックに表示されるというサンプルです。

このサンプルに手を加えて、例えばnowが「夜」かどうかをコードビハインドで判断して、夜の場合だけアニメーションを再生するというようなことはどのようにすれば可能でしょうか?

###サンプルコード

xaml

1<Window x:Class="GreetingApp.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:GreetingApp" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="450"> 9 <Canvas HorizontalAlignment="Left" Height="450" Margin="0.0,0,0,0" VerticalAlignment="Top" Width="450"> 10 <TextBlock x:Name="text" Height="100" Canvas.Left="111.688" TextWrapping="Wrap" Text="{Binding Path = Phrase}" Canvas.Top="98.052" Width="219.481" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="36"/> 11 <Button Click="Click_Morning" Content="朝" Canvas.Left="30" Canvas.Top="250" Width="100" Height="50" FontSize="24"/> 12 <Button Click="Click_Evening" Content="昼" Canvas.Left="170.26" Canvas.Top="250" Width="100" Height="50" FontSize="24"/> 13 <Button Click="Click_Night" Content="夜" Canvas.Left="310.519" Canvas.Top="250" Width="100" Height="50" FontSize="24"/> 14 <Button Click="Click_Greeting" Content="あいさつ" Canvas.Left="170.26" Canvas.Top="325.974" Width="100" Height="50" FontSize="24"/> 15 </Canvas> 16 17</Window>

c#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Linq; 5using System.Text; 6using System.Threading.Tasks; 7using System.Windows; 8using System.Windows.Controls; 9using System.Windows.Data; 10using System.Windows.Documents; 11using System.Windows.Input; 12using System.Windows.Media; 13using System.Windows.Media.Imaging; 14using System.Windows.Navigation; 15using System.Windows.Shapes; 16 17namespace GreetingApp 18{ 19 20 public enum Period { MORNING, EVENING, NIGHT }; 21 22 /// <summary> 23 /// MainWindow.xaml の相互作用ロジック 24 /// </summary> 25 public partial class MainWindow : Window 26 { 27 GreetingPhrase ph = new GreetingPhrase(); 28 29 public MainWindow() 30 { 31 InitializeComponent(); 32 DataContext = ph; 33 } 34 35 private void Click_Morning(object sender, RoutedEventArgs e) 36 { 37 ph.now = Period.MORNING; 38 } 39 40 private void Click_Evening(object sender, RoutedEventArgs e) 41 { 42 ph.now = Period.EVENING; 43 } 44 45 private void Click_Night(object sender, RoutedEventArgs e) 46 { 47 ph.now = Period.NIGHT; 48 } 49 50 private void Click_Greeting(object sender, RoutedEventArgs e) 51 { 52 ph.ChangePhrase(); 53 } 54 } 55 56 public class GreetingPhrase : INotifyPropertyChanged 57 { 58 #region INotifyPropertyChanged の実装 59 public event PropertyChangedEventHandler PropertyChanged; 60 private void RaiseProeprtyChanged(string propertyName) 61 { 62 var h = this.PropertyChanged; 63 if (h != null) h(this, new PropertyChangedEventArgs(propertyName)); 64 } 65 #endregion INotifyPropertyChanged の実装 66 67 public string Phrase { get; set; } 68 69 public Period now { get; set; } 70 71 public void ChangePhrase() 72 { 73 switch (now) 74 { 75 case Period.MORNING: 76 Phrase = "おはよう!"; 77 break; 78 case Period.EVENING: 79 Phrase = "こんにちは!"; 80 break; 81 case Period.NIGHT: 82 Phrase = "こんばんは!"; 83 break; 84 } 85 RaiseProeprtyChanged("Phrase"); 86 } 87 } 88} 89

###サンプルプログラム実行時の画面
(文字のズレはごめんなさい)
イメージ説明

###やりたかった実装
疑問が解決したのでやりたかった実装を以下に載せておきます。

C#

1using System.ComponentModel; 2using System.Windows; 3using System.Windows.Media.Animation; 4 5namespace Questions298961 6{ 7 public enum Period { MORNING, EVENING, NIGHT }; 8 9 public partial class MainWindow : Window 10 { 11 private readonly GreetingPhrase ph = new GreetingPhrase(); 12 13 public MainWindow() 14 { 15 InitializeComponent(); 16 DataContext = ph; 17 } 18 19 private void Click_Morning(object sender, RoutedEventArgs e) => ph.Now = Period.MORNING; 20 21 private void Click_Evening(object sender, RoutedEventArgs e) => ph.Now = Period.EVENING; 22 23 private void Click_Night(object sender, RoutedEventArgs e) => ph.Now = Period.NIGHT; 24 25 private void Click_Greeting(object sender, RoutedEventArgs e) 26 { 27 ph.ChangePhrase(); 28 29 //ここにアニメーション用の条件分岐を入れました。 30 switch (ph.Now) 31 { 32 case Period.MORNING: 33 var sb = FindResource("MorningAnimation") as Storyboard; 34 BeginStoryboard(sb); 35 break; 36 37 case Period.EVENING: 38 sb = FindResource("EveningAnimation") as Storyboard; 39 BeginStoryboard(sb); 40 break; 41 42 case Period.NIGHT: 43 sb = FindResource("NightAnimation") as Storyboard; 44 BeginStoryboard(sb); 45 break; 46 } 47 48 } 49 } 50 51 public class GreetingPhrase : INotifyPropertyChanged 52 { 53 public string Phrase { get; set; } 54 55 private Period _Now; 56 public Period Now 57 { 58 get => _Now; 59 set 60 { 61 _Now = value; 62 RaiseProeprtyChanged(nameof(Now)); 63 } 64 } 65 66 public void ChangePhrase() 67 { 68 switch (Now) 69 { 70 case Period.MORNING: 71 Phrase = "おはよう!"; 72 break; 73 case Period.EVENING: 74 Phrase = "こんにちは!"; 75 break; 76 case Period.NIGHT: 77 Phrase = "こんばんは!"; 78 break; 79 } 80 RaiseProeprtyChanged(nameof(Phrase)); 81 } 82 83 #region INotifyPropertyChanged の実装 84 public event PropertyChangedEventHandler PropertyChanged; 85 private void RaiseProeprtyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 86 #endregion 87 } 88}

xamlの方はTN8001さんの書いてくださったものをそのまま使えると思うので割愛します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ちょっとやりたいことが見えないので外しているかもしれませんが、3パターンでBeginStoryboardしました。
肝心のアニメーションがないので、色を変えるだけのつまらないアニメーションになってしまいました^^;

  • 朝 コードビハインドでキック
  • EventTriggerでキック
  • DataTriggerでキック

xml

1<Window 2 x:Class="Questions298961.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions298961" 6 x:Name="window" 7 Title="MainWindow" 8 Width="450" 9 Height="450"> 10 11 <Window.Resources> 12 <!-- コードビハインドでキック --> 13 <Storyboard x:Key="MorningAnimation"> 14 <ColorAnimationUsingKeyFrames Storyboard.TargetName="window" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 15 <EasingColorKeyFrame KeyTime="0:0:1" Value="#FFFFA400" /> 16 </ColorAnimationUsingKeyFrames> 17 </Storyboard> 18 <!-- EventTriggerでキック --> 19 <Storyboard x:Key="EveningAnimation"> 20 <ColorAnimationUsingKeyFrames Storyboard.TargetName="window" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 21 <EasingColorKeyFrame KeyTime="0:0:1" Value="#FF0388FF" /> 22 </ColorAnimationUsingKeyFrames> 23 </Storyboard> 24 <!-- DataTriggerでキック --> 25 <Storyboard x:Key="NightAnimation"> 26 <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 27 <EasingColorKeyFrame KeyTime="0:0:1" Value="#FF02067A" /> 28 </ColorAnimationUsingKeyFrames> 29 </Storyboard> 30 <Style TargetType="{x:Type Button}"> 31 <Setter Property="Width" Value="100" /> 32 <Setter Property="Height" Value="50" /> 33 <Setter Property="FontSize" Value="24" /> 34 </Style> 35 </Window.Resources> 36 37 <Window.Style> 38 <Style> 39 <Style.Triggers> 40 <DataTrigger Binding="{Binding Now}" Value="{x:Static local:Period.NIGHT}"> 41 <DataTrigger.EnterActions> 42 <BeginStoryboard Storyboard="{StaticResource NightAnimation}" /> 43 </DataTrigger.EnterActions> 44 </DataTrigger> 45 </Style.Triggers> 46 </Style> 47 </Window.Style> 48 49 <Canvas> 50 <TextBlock 51 Canvas.Left="111" 52 Canvas.Top="98" 53 Width="219" 54 Height="100" 55 FontSize="36" 56 Text="{Binding Path=Phrase}" 57 TextWrapping="Wrap" /> 58 <Button 59 Canvas.Left="30" 60 Canvas.Top="250" 61 Click="Click_Morning" 62 Content="" /> 63 <Button 64 Canvas.Left="170" 65 Canvas.Top="250" 66 Click="Click_Evening" 67 Content=""> 68 <Button.Triggers> 69 <EventTrigger RoutedEvent="Button.Click"> 70 <BeginStoryboard Storyboard="{StaticResource EveningAnimation}" /> 71 </EventTrigger> 72 </Button.Triggers> 73 </Button> 74 <Button 75 Canvas.Left="310" 76 Canvas.Top="250" 77 Click="Click_Night" 78 Content="" /> 79 <Button 80 Canvas.Left="170" 81 Canvas.Top="325" 82 Click="Click_Greeting" 83 Content="あいさつ" /> 84 </Canvas> 85</Window>

cs

1using System.ComponentModel; 2using System.Windows; 3using System.Windows.Media.Animation; 4 5namespace Questions298961 6{ 7 public enum Period { MORNING, EVENING, NIGHT }; 8 9 public partial class MainWindow : Window 10 { 11 private readonly GreetingPhrase ph = new GreetingPhrase(); 12 13 public MainWindow() 14 { 15 InitializeComponent(); 16 DataContext = ph; 17 } 18 19 private void Click_Morning(object sender, RoutedEventArgs e) 20 { 21 ph.Now = Period.MORNING; 22 var sb = FindResource("MorningAnimation") as Storyboard; 23 BeginStoryboard(sb); 24 } 25 26 private void Click_Evening(object sender, RoutedEventArgs e) => ph.Now = Period.EVENING; 27 28 private void Click_Night(object sender, RoutedEventArgs e) => ph.Now = Period.NIGHT; 29 30 private void Click_Greeting(object sender, RoutedEventArgs e) => ph.ChangePhrase(); 31 } 32 33 public class GreetingPhrase : INotifyPropertyChanged 34 { 35 public string Phrase { get; set; } 36 37 private Period _Now; 38 public Period Now 39 { 40 get => _Now; 41 set 42 { 43 _Now = value; 44 RaiseProeprtyChanged(nameof(Now)); 45 } 46 } 47 48 public void ChangePhrase() 49 { 50 switch(Now) 51 { 52 case Period.MORNING: 53 Phrase = "おはよう!"; 54 break; 55 case Period.EVENING: 56 Phrase = "こんにちは!"; 57 break; 58 case Period.NIGHT: 59 Phrase = "こんばんは!"; 60 break; 61 } 62 RaiseProeprtyChanged(nameof(Phrase)); 63 } 64 65 #region INotifyPropertyChanged の実装 66 public event PropertyChangedEventHandler PropertyChanged; 67 private void RaiseProeprtyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 68 #endregion 69 } 70}

アプリ動画

投稿2020/10/19 10:24

編集2023/07/23 08:09
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/10/20 05:55 編集

3通りものご回答をありがとうございます! わかりにくい質問となっていて申し訳ないです。 質問の意図としてはClick_Greetingの処理内でph.Nowの状態(朝or昼or夜)を見てそれぞれに対応したアニメーションを再生するということがやりたかったです。 なので、コードビハインドでキックするパターンを使えば簡単に実装できました。 参考までに、やりたかった実装も質問文に追記しておきますね。 (疑問は解決しましたのでわざわざ見ていただく必要はないです。) 今回の挨拶アプリは例として急いで作ったものでしたが、おかげさまで本当に作りたいものの方もうまくアニメーションを実装できそうです。 3通りも提示していただいたおかげで、だいぶWPFのアニメーションについての理解も深まりました。 いつもありがとうございます。
退会済みユーザー

退会済みユーザー

2020/10/20 06:44

質問の追加で申し訳ないのですが、FindResource()やBeginStoryboard()といった関数は、MainWindowクラス外(サンプルコードで言えばGreetingPhraseクラス内の関数などで)は使えないのでしょうか? 現在それをしようとしてコンパイルエラーが起きており、、、MainWindowクラス内であれば全く同じ関数が使えるのですが。 MainWindowクラス外で上記関数を使う方法があれば教えていただきたいです。 モデル側で条件を満たしたときにストーリーボードに設定したアニメーションを開始したく、上記のような状況になっております。
退会済みユーザー

退会済みユーザー

2020/10/20 07:44

すみません、自己解決しました。 Application.Current.MainWindowでMainWindowのインスタンス(?)を生成すればいいようですね。 お騒がせしました。
TN8001

2020/10/20 08:47

>MainWindowのインスタンス(?)を生成すればいいようですね。 取得ですね。 ModelにViewが漏れ出すのは気持ちが悪いですが、まあいいんじゃないですかね。 DataTriggerでやれると思いましたが、この例だと明らかに不完全でしたね。 3stateだと制御が難しくて諦めました^^;(コードビハインドなら簡単なのに。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問