@Grabacr07さんの素敵な記事!
Thumb コントロールで Photoshop のナビゲーターを再現するgrabacr.net
WinRTでやるときはこうだよっていうのをちょっとだけ。主にScrollViewerがいけてない部分を補足するだけです。ScrollViewerのScrollChangedイベントはWinRTにはないので、ViewChangedイベントと、LayoutUpdatedイベントを組み合わせて同じような動きを再現させます。コード的には以下のような感じ。
privatevoid ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { this.UpdateViewportSize(); } privatevoid ScrollViewer_LayoutUpdated(object sender, object e) { this.UpdateViewportSize(); } privatevoid UpdateViewportSize() { var xfactor = this.Thumbnail.ActualWidth / this.ScrollViewer.ExtentWidth; var yfactor = this.Thumbnail.ActualHeight / this.ScrollViewer.ExtentHeight; var left = this.ScrollViewer.HorizontalOffset * xfactor; var top = this.ScrollViewer.VerticalOffset * yfactor; var width = this.ScrollViewer.ViewportWidth * xfactor; if (width > this.Thumbnail.ActualWidth) { width = this.Thumbnail.ActualWidth; } var height = this.ScrollViewer.ViewportHeight * yfactor; if (height > this.Thumbnail.ActualHeight) { height = this.Thumbnail.ActualHeight; } Canvas.SetTop(this.Viewport, top); Canvas.SetLeft(this.Viewport, left); this.Viewport.Width = width; this.Viewport.Height = height; }
これだけで、WinRTでも動くようになります。(試したのはWin10TPのUAPだけどたぶん大丈夫でしょう…)
コード
一応XAMLとC#のコードをはっておきます。
<Pagex:Class="App24.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:App24"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition/></Grid.ColumnDefinitions><Canvas Margin="10"Width="{Binding Path=ActualWidth, ElementName=Thumbnail}"Height="{Binding Path=ActualHeight, ElementName=Thumbnail}"HorizontalAlignment="Center"><Image x:Name="Thumbnail"Width="100"Stretch="Uniform"Source="ms-appx:///Assets/tree.jpg" /><Thumb x:Name="Viewport"DragDelta="Viewport_DragDelta"><Thumb.Template><ControlTemplate TargetType="Thumb"><Border BorderThickness="2"BorderBrush="Red"Background="Transparent" /></ControlTemplate></Thumb.Template></Thumb></Canvas><ScrollViewer x:Name="ScrollViewer"Grid.Column="1"VerticalScrollBarVisibility="Auto"HorizontalScrollBarVisibility="Auto"ViewChanged="ScrollViewer_ViewChanged"LayoutUpdated="ScrollViewer_LayoutUpdated"><Image Source="ms-appx:///Assets/tree.jpg" /></ScrollViewer></Grid></Page>
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409namespace App24 { /// <summary>/// An empty page that can be used on its own or navigated to within a Frame./// </summary>publicsealedpartialclass MainPage : Page { public MainPage() { this.InitializeComponent(); } privatevoid ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { this.UpdateViewportSize(); } privatevoid ScrollViewer_LayoutUpdated(object sender, object e) { this.UpdateViewportSize(); } privatevoid UpdateViewportSize() { var xfactor = this.Thumbnail.ActualWidth / this.ScrollViewer.ExtentWidth; var yfactor = this.Thumbnail.ActualHeight / this.ScrollViewer.ExtentHeight; var left = this.ScrollViewer.HorizontalOffset * xfactor; var top = this.ScrollViewer.VerticalOffset * yfactor; var width = this.ScrollViewer.ViewportWidth * xfactor; if (width > this.Thumbnail.ActualWidth) { width = this.Thumbnail.ActualWidth; } var height = this.ScrollViewer.ViewportHeight * yfactor; if (height > this.Thumbnail.ActualHeight) { height = this.Thumbnail.ActualHeight; } Canvas.SetTop(this.Viewport, top); Canvas.SetLeft(this.Viewport, left); this.Viewport.Width = width; this.Viewport.Height = height; } privatevoid Viewport_DragDelta(object sender, DragDeltaEventArgs e) { this.ScrollViewer.ScrollToHorizontalOffset( this.ScrollViewer.HorizontalOffset + (e.HorizontalChange * this.ScrollViewer.ExtentWidth / this.Viewport.ActualWidth)); this.ScrollViewer.ScrollToVerticalOffset( this.ScrollViewer.VerticalOffset + (e.VerticalChange * this.ScrollViewer.ExtentHeight / this.Viewport.ActualHeight)); } } }