Yandex MapKitをピボットおよびパノラマコントロールと組み合わせて使用​​する

アプリケーションのメインページは、Pivo​​tコントロールを使用して構築され、ブックマークの1つには、車の位置に関する情報を含む地図を配置する必要がありました。 このアプリケーションのユーザーは、MicrosoftとYandexのマップサービスから選択することを決定しました。



統合マップサービスの統合は難しくありませんでした。マップを表示するためのコントロールはオペレーティングシステムの一部であり、すべての標準コントロールとの統合は細部にわたって行われているためです。



ただし、YandexのYandex.Map MapKitに含まれるマップを表示するためのコントロールの統合により、予期しない問題が発生しました。 マップを水平方向に操作しようとすると、Pivo​​tコントロールの現在のタブが切り替わります。



この問題の研究により、Windows Phone 8でジェスチャーが最適化されたことが示されました。 その結果、ユーザー操作イベントは、子コントロールに渡される前に、組み込みコントロールによってインターセプトされます。 イベントは、DrawingSurface、DrawingSurfaceBackgroundGrid、ListBox、LongListSelector、Map、Panorama、Pivo​​t、ScrollViewer、ViewportControl、WebBrowserの各コントロールによってインターセプトされます。



残念ながら、Yandex.Maps MapKitツールキットはYandexでサポートされなくなり、利用可能な最新バージョンは、これらの最適化が欠落しているWindows Phone 7.5用に開発されています。



コントロールのUseOptimizedManipulationRoutingプロパティをfalseに設定することにより、オペレーティングシステムの最適化をオフにできます。 ただし、プロパティ値を設定した後、アプリケーションの動作は変更されていません。 問題は、コントロールのジェスチャ処理を有効にすることで、イベントを処理する必要があることです: ManipulationStartedManipulationDeltaおよびManipulationCompleted 。 Mapコントロールはこれを処理するため、これらのハンドラーでユーザージェスチャを処理する必要はありません。Handledフラグをtrueに設定し、イベントが既に処理されたことを他のコントロールに通知するだけです。



説明したアクションの後、アプリケーションは期待どおりに動作を開始します。つまり、すべてのプレーンでマップを操作するとき、ピボットコントロールの現在のタブは変更されません。



これらのアクションは、アタッチ可能なプロパティを実装し、ハンドラーで説明した上記のすべてを実装することにより、宣言レベルに転送できます。



using System.Windows; using Yandex.Maps; namespace YandexMapKit { public static class YandexMapHelper { public static readonly DependencyProperty FixManipulationProperty = DependencyProperty.RegisterAttached( "FixManipulation", typeof(bool), typeof(YandexMapHelper), new PropertyMetadata(OnFixManipulationChanged)); public static void SetFixManipulation(DependencyObject element, bool value) { element.SetValue(FixManipulationProperty, value); } public static bool GetFixManipulation(DependencyObject element) { return (bool) element.GetValue(FixManipulationProperty); } private static void OnFixManipulationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var map = d as Map; if (map == null) { return; } var fixManipulation = (bool?) e.NewValue; if (fixManipulation == true) { map.UseOptimizedManipulationRouting = false; map.ManipulationStarted += MapManipulationStarted; map.ManipulationCompleted += MapManipulationCompleted; map.ManipulationDelta += MapManipulationDelta; return; } fixManipulation = (bool?)e.OldValue; if (fixManipulation == true) { map.UseOptimizedManipulationRouting = true; map.ManipulationStarted -= MapManipulationStarted; map.ManipulationCompleted -= MapManipulationCompleted; map.ManipulationDelta -= MapManipulationDelta; } } private static void MapManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e) { e.Handled = true; } private static void MapManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e) { e.Handled = true; } private static void MapManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e) { e.Handled = true; } } }
      
      







これで、追加のコードを記述することなく、ページレイアウトのMapコントロールのこのプロパティをtrueに設定できます。



 <phone:Pivot Title="YANDEX MAPKIT TEST APP"> <phone:PivotItem Header=""> <StackPanel> <RichTextBox VerticalAlignment="Top" VerticalContentAlignment="Top"> <Paragraph> <Run Text="     Map    Yandex.Maps MapKit       Pivot"/> </Paragraph> </RichTextBox> <CheckBox x:Name="viewFixManipulation" Content=" " VerticalAlignment="Top" /> </StackPanel> </phone:PivotItem> <phone:PivotItem Header=""> <Grid> <yandexMaps:Map yandexMapKit:YandexMapHelper.FixManipulation="{Binding IsChecked, ElementName=viewFixManipulation}" /> </Grid> </phone:PivotItem> </phone:Pivot>
      
      







上記のすべては、スライダーコントロールなど、水平方向のユーザージェスチャが重要な他のコントロールに適用されます。 添付プロパティのコードをわずかに変更することにより、コードを汎用化し、水平方向のユーザージェスチャを処理する必要があるコントロールで使用できます。



GitHubで利用可能なテストプロジェクト



All Articles