かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

FlipViewの上下移動のボタンをクリックしたときにTappedイベントが発生してしまうのをどうにかしたい

表題の通り、FlipViewのTappedイベントで画面遷移を行う処理を書いていたら、マウスのときにFlipViewに表示される上下移動のためのボタンをクリックしただけで画面遷移するようになって悩んでました。

同じ問題に悩んでる人が海外にもいたみたいで話題になってたのを見て解決しました。

上記ページのままですが、仕掛けとしては、FlipViewのVisualTree上にあるボタンをとってきてTappedイベントを仕掛けてe.Handled = trueしてやることでFlipViewまでイベントを上げないようにするという感じです。

コードにすると、こんなユーテリティを用意します。

public static class VisualTreeHelperExtensions
{
    public static IEnumerable<T> GetDescendantsOfType<T>(FrameworkElement target)
        where T : DependencyObject
    {
        return GetDescendants(target).OfType<T>();
    }

    public static IEnumerable<DependencyObject> GetDescendants(DependencyObject target)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(target); i++)
        {
            var r = VisualTreeHelper.GetChild(target, i);
            yield return r;
            foreach (var c in GetDescendants(r))
            {
                yield return c;
            }
        }
    }
}

そして、FlipViewのLoadedイベントで以下のようなコードを書きます。

private void FlipView_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    var flipView = (FlipView)sender;
    var buttons = VisualTreeHelperExtensions.GetDescendantsOfType<Button>(flipView);
    foreach (var button in buttons)
    {
        button.Tapped += (_, args) => args.Handled = true;
    }
}

Behaviorにまとめてしまってもいいかもしれませんね。