かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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にまとめてしまってもいいかもしれませんね。