none
ScrollViewer中のButtonを指タッチしても画像が変わらない(マウスクリックでは画像が変わる) RRS feed

  • 質問

  • 現在タッチ可能なWindows8端末でWPF開発を行っております。

    下記のxamlにて、ScrollViewer中にWrapPanelをかませ、Buttonを縦に10個表示させています。
    ButtonはTriggersを使用して、指タッチ(左クリック)した時に画像が変わるようにしています。
     デフォルト画像=button_normal.png
     タッチ中("IsPressed"=True)画像=button_press.png

        <Grid Width="525" Height="350">
            <ScrollViewer  x:Name="scrollView" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled" PanningMode="VerticalOnly" CanContentScroll="False">
                <ScrollViewer.Resources>
                    <Style TargetType="{x:Type Button}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type Button}">
                                    <Grid>
                                        <Image Name="normalImage" Source="Resources/button_normal.png"></Image>
                                        <Image Name="pressImage" Source="Resources/button_press.png" Visibility="Collapsed"></Image>
                                        <ContentPresenter Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center"></ContentPresenter>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsPressed" Value="True">
                                            <Setter TargetName="normalImage" Property="Visibility" Value="Collapsed"></Setter>
                                            <Setter TargetName="pressImage" Property="Visibility" Value="Visible"></Setter>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ScrollViewer.Resources>
                <WrapPanel x:Name="wrapPanel" Orientation="Vertical" VerticalAlignment="TOP" HorizontalAlignment="LEFT">
                    <Button Content="button1" Width="525" Height="100"/>
                    <Button Content="button2" Width="525" Height="100"/>
                    <Button Content="button3" Width="525" Height="100"/>
                    <Button Content="button4" Width="525" Height="100"/>
                    <Button Content="button5" Width="525" Height="100"/>
                    <Button Content="button6" Width="525" Height="100"/>
                    <Button Content="button7" Width="525" Height="100"/>
    		<Button Content="button8" Width="525" Height="100"/>
                    <Button Content="button9" Width="525" Height="100"/>
                    <Button Content="button10" Width="525" Height="100"/>
                </WrapPanel>
            </ScrollViewer>
        </Grid>

    しかしながら、上記レイアウトをビルドしたところ
    マウス左クリックではButton画像が正常にbutton_press.pngに変わるのですが
    指タッチでButtonを押した時は画像が変わらず、button_normal.pngのままになってしまいます。
    csファイルは特に何も実装しておりません。

    ScrollViewer中でボタンをタッチした際に画像を差し替えるには
    どのような実装を行えばよいか、ご存知でしたらご教授いただけませんでしょうか。
    できればマウスクリックと指タッチで、ソースを替えたくないと考えております。(できればで結構です)
    お手数ですがよろしくお願い致します。



    • 編集済み kkwin8 2014年1月21日 12:28
    2014年1月21日 10:06

回答

  • Azulean

    ご返信誠にありがとうございます。そしてご連絡遅くなり申し訳ありません。

    ご教授いただいたイベントトリガーを使用する方法を試させていただいたのですが

    タッチイベント発生時にトリガーがうまく発生せず、実行させることができませんでした。

    こちらで調査したところ、指でタッチした場合に、ButtonコントロールのIsPressedプロパティがfalseのままで

    triggerが動いていないことが原因でした。

    そこで、下記のようなタッチを判定する追加プロパティ"IsTouched"を持つカスタムボタンを実装し

    "IsTouched"をトリガーに追加することで、タッチでも画像が変わるようになりました。

    <カスタムボタン>

        /// <summary>
        /// 指タッチされているかどうかを判断するプロパティ"IsTouched"を追加したカスタムボタン
        /// </summary>
        public class TouchEnableButton : Button
        {
            /// <summary>
            /// TouchEnableButtonが現在指によってタッチされているかどうかを取得する
            /// </summary>
            public bool IsTouched
            {
                get { return (bool)GetValue(IsTouchingProperty); }
                set { SetValue(IsTouchingProperty, value); }
            }
    
            public static readonly DependencyProperty IsTouchingProperty =
                DependencyProperty.Register("IsTouched", typeof(bool), typeof(TouchEnableButton));
        }

    <タッチされた時に、IsTouchedプロパティを変更する>

    	//タッチダウンイベント
    	private void TouchEnableButton_TouchDown(object sender, TouchEventArgs e)
    	{
             TouchEnableButton button = sender as TouchEnableButton;
             button.IsTouched = true; //ボタンが押された
        }
    	
    	//タッチアップイベント
    	private void TouchEnableButton_TouchUp(object sender, TouchEventArgs e)
    	{
             TouchEnableButton button = sender as TouchEnableButton;
             button.IsTouched = false; //ボタンが離された
        }


    <IsTouched プロパティをtriggerに追加>

                    <Style TargetType="mypackage:TouchEnableButton">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="mypackage:TouchEnableButton">
                                    <Grid>
                                        <Image Name="normalImage" Source="Resources/button_normal.png"></Image>
                                        <Image Name="pressImage" Source="Resources/button_press.png" Visibility="Collapsed"></Image>
                                        <ContentPresenter Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center"></ContentPresenter>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsPressed" Value="True">
                                            <Setter TargetName="normalImage" Property="Visibility" Value="Collapsed"></Setter>
                                            <Setter TargetName="pressImage" Property="Visibility" Value="Visible"></Setter>
                                        </Trigger>
    									 <Trigger Property="IsTouched" Value="true"> <!-- 指タッチ用-->
                                            <Setter TargetName="normalImage" Property="Visibility" Value="Collapsed"></Setter>
                                            <Setter TargetName="pressImage" Property="Visibility" Value="Visible"></Setter>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
    	

    星 様

    自己解決となりましたが、こちらの方に回答マークをつけさせていただきます。

    Azulean様も情報いただき、誠にありがとうございました。

    • 回答としてマーク kkwin8 2014年2月4日 7:07
    2014年2月4日 7:06

すべての返信

  • トリガーを増やしてみるとか。
    http://social.msdn.microsoft.com/Forums/vstudio/en-US/1e65c51e-0d60-4074-8476-22c030f18364/ispressed-property-trigger-for-touch

    (試していませんが、それらしいコードだったので投稿させていただきました。すでに確認されていればすみません。
    タッチ操作とマウスの操作はイコールにはなりませんので、ある程度、違う部分が生じるのは仕方ないのかもしれません)

    • 回答の候補に設定 星 睦美 2014年1月27日 4:07
    2014年1月21日 14:12
  • kkwin8 さん、こんにちは。
    フォーラム オペレーターの星 睦美です。

    私のほうでAzulean さんの返信がヒントになりそうだと思いましたので、[回答の候補に設定] させていただきました。引き続き質問したい点がありましたら、返信いただければと思います。

    フォーラムで役立つ回答には、投稿者から[回答としてマーク]をお願いします。


    フォーラム オペレーター 星 睦美 - MSDN Community Support

    2014年1月27日 4:10
  • Azulean

    ご返信誠にありがとうございます。そしてご連絡遅くなり申し訳ありません。

    ご教授いただいたイベントトリガーを使用する方法を試させていただいたのですが

    タッチイベント発生時にトリガーがうまく発生せず、実行させることができませんでした。

    こちらで調査したところ、指でタッチした場合に、ButtonコントロールのIsPressedプロパティがfalseのままで

    triggerが動いていないことが原因でした。

    そこで、下記のようなタッチを判定する追加プロパティ"IsTouched"を持つカスタムボタンを実装し

    "IsTouched"をトリガーに追加することで、タッチでも画像が変わるようになりました。

    <カスタムボタン>

        /// <summary>
        /// 指タッチされているかどうかを判断するプロパティ"IsTouched"を追加したカスタムボタン
        /// </summary>
        public class TouchEnableButton : Button
        {
            /// <summary>
            /// TouchEnableButtonが現在指によってタッチされているかどうかを取得する
            /// </summary>
            public bool IsTouched
            {
                get { return (bool)GetValue(IsTouchingProperty); }
                set { SetValue(IsTouchingProperty, value); }
            }
    
            public static readonly DependencyProperty IsTouchingProperty =
                DependencyProperty.Register("IsTouched", typeof(bool), typeof(TouchEnableButton));
        }

    <タッチされた時に、IsTouchedプロパティを変更する>

    	//タッチダウンイベント
    	private void TouchEnableButton_TouchDown(object sender, TouchEventArgs e)
    	{
             TouchEnableButton button = sender as TouchEnableButton;
             button.IsTouched = true; //ボタンが押された
        }
    	
    	//タッチアップイベント
    	private void TouchEnableButton_TouchUp(object sender, TouchEventArgs e)
    	{
             TouchEnableButton button = sender as TouchEnableButton;
             button.IsTouched = false; //ボタンが離された
        }


    <IsTouched プロパティをtriggerに追加>

                    <Style TargetType="mypackage:TouchEnableButton">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="mypackage:TouchEnableButton">
                                    <Grid>
                                        <Image Name="normalImage" Source="Resources/button_normal.png"></Image>
                                        <Image Name="pressImage" Source="Resources/button_press.png" Visibility="Collapsed"></Image>
                                        <ContentPresenter Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center"></ContentPresenter>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsPressed" Value="True">
                                            <Setter TargetName="normalImage" Property="Visibility" Value="Collapsed"></Setter>
                                            <Setter TargetName="pressImage" Property="Visibility" Value="Visible"></Setter>
                                        </Trigger>
    									 <Trigger Property="IsTouched" Value="true"> <!-- 指タッチ用-->
                                            <Setter TargetName="normalImage" Property="Visibility" Value="Collapsed"></Setter>
                                            <Setter TargetName="pressImage" Property="Visibility" Value="Visible"></Setter>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
    	

    星 様

    自己解決となりましたが、こちらの方に回答マークをつけさせていただきます。

    Azulean様も情報いただき、誠にありがとうございました。

    • 回答としてマーク kkwin8 2014年2月4日 7:07
    2014年2月4日 7:06