回答済み ボタンを押してアニメーションを実現したい

  • 2012年5月1日 12:50
     
      コードあり

    業務で1年、趣味で2年ほどやっていますがもう本当にWPFというのとてつもなく難しく、本に沿ってやってもわずかな応用しようとするだけでうまくいかなかったりまるでやり方不明になってしまうので、迷惑で恥ずかしながら単純なことでも質問させていただきます。

    <Window x:Class="GUI.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Style x:Name="Style1" TargetType="Button" >
                <Style.Triggers>
                    <Trigger  Property="ButtonBase.IsPressed" Value="true">
                        <Trigger.EnterActions>
                            <BeginStoryboard Name="BeginStoryboard2">
                                <BeginStoryboard.Storyboard>
                                    <Storyboard>
                                        <ThicknessAnimation Storyboard.TargetName="Ellipse1"  Storyboard.TargetProperty="Margin" Duration="0:0:1" From="0,120,400,150" To="300,120,0,150" />
                                    </Storyboard>
                                </BeginStoryboard.Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </Style.Triggers>
    
            </Style>
        </Window.Resources>
        <Grid>
            <Ellipse Name="Ellipse1" Width="32" Height="32"  Fill="Blue" Margin="108,113,363,166" />
            <Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="370,19,0,0" Name="button1" VerticalAlignment="Top" Width="75" Style="Style1" >
            </Button>
        </Grid>
    </Window>
    

    ボタンを押すと丸い図形が左から右に移動するアニメーションを実現したいのですが、↑だと

    エラー	1	Style Setter で TargetName プロパティを設定することはできません。 行 13 位置 57.	C:\Users\kazuhiro\documents\visual studio 2010\Projects\スケーラブルソケットサーバー\GUI\MainWindow.xaml	13	57	GUI
    
    と出てしまいます。どのように記述すればよいでしょうか?

すべての返信

  • 2012年5月2日 0:53
     
     回答済み コードあり

    buttonという名前のボタンを押したときにStoryboard1を起動するTriggerは以下のように書くことが出来ます。

    <Window.Resources> <Storyboard x:Key="Storyboard1">

    </Storyboard> </Window.Resources> <Window.Triggers> <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button"> <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/> </EventTrigger> </Window.Triggers>

    Styleの中ではTargetNameは指定できないみたいなので、上記のような感じではどうでしょうか。


    かずき Blog:http://d.hatena.ne.jp/okazuki/ VS 2010のデザイナでBlendのBehaviorをサポートするツール公開してます。 http://vsbehaviorsupport.codeplex.com/



  • 2012年5月2日 8:23
     
      コードあり

    かずきさんありがとうございました。

    質問の答えそのもので助かりました。

    次もあるのですが、ボタンのClickイベントによりStoryboardを起動できたので次に独自のWindowイベントで起動させたいです。

    XAMLは、

    <Window x:Class="GUI.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" x:Name="window1">
        <Window.Resources>
            <Storyboard x:Key="Storyboard1">
                <ThicknessAnimation Storyboard.TargetName="Ellipse1"  Storyboard.TargetProperty="Margin" Duration="0:0:1" From="0,120,400,150" To="300,120,0,150" />
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger RoutedEvent="GUI.MainWindow.ON状態" SourceName="window1">
                <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
            </EventTrigger>
        </Window.Triggers>
        <Grid>
            <Ellipse Name="Ellipse1" Width="32" Height="32"  Fill="Blue" Margin="108,113,363,166" />
            <Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="370,19,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click"  />
        </Grid>
    </Window>

    コードビハインドは

    using System.Windows;
    namespace GUI {
        public partial class MainWindow:Window {
            public MainWindow() {
                InitializeComponent();
                ON状態+=() => this.Title="ON";
            }
            delegate void delegateON状態();
            private event delegateON状態 ON状態;
            private void button1_Click(object sender,RoutedEventArgs e) {
                ON状態();
            }
        }
    }
    

    つまりButton.Clickで間接的にWindowが持っているイベントを発生させ、そのイベントからStoryboardを起動させたいのです。

    しかし実行時に

    ''System.Windows.Baml2006.TypeConverterMarkupExtension' の値の指定時に例外がスローされました。' 行番号 '11'、行位置 '10'。
    とでます。おそらくRoutedEventの書き方がまずいと思うのですがどう書けばよろしいでしょうか?

  • 2012年5月3日 12:51
     
      コードあり

    EventTriggerはRoutedEventという名前の通りRoutedEventじゃないとダメっぽいですね。ということで、下記のようになります。

    コードビハインドでのイベントの定義

    public static RoutedEvent SampleEvent = EventManager.RegisterRoutedEvent(
        "Sample", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(MainWindow));
    
    public event RoutedEventHandler Sample
    {
        add { this.AddHandler(SampleEvent, value); }
        remove { this.RemoveHandler(SampleEvent, value); }
    }

    XAMLでのEventTriggerの定義

    <Window x:Class="AnimationWpfApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:l="clr-namespace:MainWindowの名前空間"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Storyboard x:Key="storyboard1">
                <!-- アニメーションの定義 -->
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <!-- MainWindowで定義したSampleイベントを指定する -->
            <EventTrigger RoutedEvent="l:MainWindow.Sample">
                <BeginStoryboard Storyboard="{StaticResource storyboard1}" />
            </EventTrigger>
        </Window.Triggers>
        
        <Grid>
            <!-- 省略 -->
        </Grid>
    </Window>

    そして、ボタンのクリックイベントハンドラあたりでSampleイベントを発行するコードは以下のようになります。

    this.RaiseEvent(new RoutedEventArgs(SampleEvent, this));

    こんな感じで回答になってるでしょうか?WPFのイベントはRoutedEventという特殊なものなので、WPFをやるのでしたらそちらを抑えておいたほうがいいと思います。

    あと、WPF組み込みのTriggerとかよりも高機能なものとしてBlend SDKのTrigger(Blend SDK Behaviorで検索すると情報がヒットすると思います)というものがあります。名前が同じなので混同しやすいですが別物で、WPF組み込みのものよりも汎用的かつ高機能になってます。どんな背景や要求にこたえるためのアプリケーションを組んでいるのかわからないので何とも言えませんが、Blend SDKが使えるならそっちを使ったほうが楽できるかな~と思います。


    かずき Blog:http://d.hatena.ne.jp/okazuki/


  • 2012年5月5日 12:34
     
      コードあり

    ありがとうございます。返答を参考にxamlとコードを書きました。

    using System.Windows;
    namespace WPFテスト {
        public partial class ボタンクリックでアニメーション:Window {
            public ボタンクリックでアニメーション() {
                InitializeComponent();
            }
            public static RoutedEvent SampleEvent=EventManager.RegisterRoutedEvent(
                "Sample",RoutingStrategy.Tunnel,typeof(RoutedEventHandler),typeof(MainWindow));
    
            public event RoutedEventHandler Sample {
                add { this.AddHandler(SampleEvent,value); }
                remove { this.RemoveHandler(SampleEvent,value); }
            }
        }
    }
    
    <Window x:Class="WPFテスト.ボタンクリックでアニメーション"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:l="clr-namespace:WPFテスト"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Storyboard x:Key="storyboard1">
                <ThicknessAnimation Storyboard.TargetName="Ellipse1"  Storyboard.TargetProperty="Margin" Duration="0:0:1" From="0,120,400,150" To="300,120,0,150" />
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <!-- MainWindowで定義したSampleイベントを指定する -->
            <EventTrigger RoutedEvent="l:ボタンクリックでアニメーション.Sample">
                <BeginStoryboard Storyboard="{StaticResource storyboard1}" />
            </EventTrigger>
        </Window.Triggers>    
        <Grid>
            <Ellipse Name="Ellipse1" Width="32" Height="32"  Fill="Blue" Margin="108,113,363,166" />
            <Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="370,19,0,0" Name="button1" VerticalAlignment="Top" Width="75" />        
        </Grid>
    </Window>
    

    これで合っているかと思いましたが実行すると

    ''System.Windows.Baml2006.TypeConverterMarkupExtension' の値の指定時に例外がスローされました。' 行番号 '13'、行位置 '10'。
    と出てしまいます。