[C#] Metro アプリでコントロールをドラッグする

[C#] WPFのThumbコントロールを使ってドラッグを実装する | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/3701
[C#] Thumbコントロールを継承したユーザコントロールを作る | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/3709

上記なところで、WPF を使ってコントロールをドラッグできるようにしましたが、今回は Metro アプリで再確認してみます。中身は XAML 形式なのでそのまま動くと思うのですが、どんな風になるのかなと。

  1. Thumb コントロールを使う。
  2. ドラッグ対象の Thumb コントロールを canvas の中に置く。
  3. Thumb コントロールのテンプレートに、画像を貼りつけるための Ellipse タグを用意する。
  4. Thumb コントロールのハンドラは後付け(複数配置するため)

ざっと、ソースコードだけ晒しておきます。

デザインはこんな感じ

▼MainPage.xaml

<Page
    x:Class=&quot;KeshoSlidePazzle.MainPage&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:local=&quot;using:KeshoSlidePazzle&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot;>
    <Page.Resources>
        <ControlTemplate TargetType=&quot;Thumb&quot; x:Name=&quot;ImageThumb&quot;>
            <Ellipse Fill=&quot;{TemplateBinding Background}&quot;></Ellipse>
        </ControlTemplate>
    </Page.Resources>

    <Grid Background=&quot;{StaticResource ApplicationPageBackgroundThemeBrush}&quot;>
            <TextBlock HorizontalAlignment=&quot;Left&quot; Margin=&quot;10,10,0,0&quot; TextWrapping=&quot;Wrap&quot; Text=&quot;Kesho Slide Pazzle&quot; VerticalAlignment=&quot;Top&quot; Height=&quot;56&quot; Width=&quot;327&quot; FontSize=&quot;24&quot;/>
        <Canvas HorizontalAlignment=&quot;Left&quot; Height=&quot;692&quot; Margin=&quot;191,94,0,-18&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;866&quot;>
            <Thumb Canvas.Left=&quot;345&quot; Canvas.Top=&quot;99&quot; Height=&quot;143&quot; Name=&quot;mark1&quot;  Width=&quot;144&quot;
                   Template=&quot;{StaticResource ImageThumb}&quot;
                   ></Thumb>
            <Thumb Canvas.Left=&quot;55&quot; Canvas.Top=&quot;73&quot; Height=&quot;143&quot; Name=&quot;mark2&quot;  Width=&quot;144&quot;
                   Template=&quot;{StaticResource ImageThumb}&quot;
                ></Thumb>
        </Canvas>

    </Grid>
</Page>

▼MainPage.xaml.cs

/// <summary>
/// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
/// </summary>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    /// <summary>
    /// このページがフレームに表示されるときに呼び出されます。
    /// </summary>
    /// <param name=&quot;e&quot;>このページにどのように到達したかを説明するイベント データ。Parameter 
    /// プロパティは、通常、ページを構成するために使用します。</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        mark1.Background = getBrush(&quot;koma1.png&quot;); setHandler(mark1);
        mark2.Background = getBrush(&quot;koma2.png&quot;); setHandler(mark2);
    }

    /// <summary>
    /// 画像を設定
    /// </summary>
    /// <param name=&quot;file&quot;></param>
    /// <returns></returns>
    private ImageBrush getBrush( string file ) 
    {
        var bmp = new BitmapImage(new Uri(&quot;ms-appx:///Assets/&quot; + file));
        var br = new ImageBrush();
        br.ImageSource = bmp;
        return br;
    }
    /// <summary>
    /// ハンドラを設定
    /// </summary>
    /// <param name=&quot;t&quot;></param>
    private void setHandler(Thumb t)
    {
        t.DragCompleted += mark_DragCompleted;
        t.DragDelta += mark_DragDelta;
        t.DragStarted += mark_DragStarted;
    }


    /// <summary>
    /// ドラッグ終了
    /// </summary>
    /// <param name=&quot;sender&quot;></param>
    /// <param name=&quot;e&quot;></param>
    private void mark_DragCompleted(object sender, DragCompletedEventArgs e)
    {
        var t = sender as Thumb;
        t.Opacity = 1.0;
    }

    /// <summary>
    /// ドラッグ開始
    /// </summary>
    /// <param name=&quot;sender&quot;></param>
    /// <param name=&quot;e&quot;></param>
    private void mark_DragStarted(object sender, DragStartedEventArgs e)
    {
        var t = sender as Thumb;
        t.Opacity = 0.5;
    }

    /// <summary>
    /// ドラック中
    /// </summary>
    /// <param name=&quot;sender&quot;></param>
    /// <param name=&quot;e&quot;></param>
    private void mark_DragDelta(object sender, DragDeltaEventArgs e)
    {
        var t = sender as Thumb;
        Canvas.SetLeft(t, Canvas.GetLeft(t) + e.HorizontalChange);
        Canvas.SetTop(t, Canvas.GetTop(t) + e.VerticalChange);
    }
}

実は、Ellipse のような普通のコントロールにもドラッグの機能は備わっている…というか、マウスイベントをキャプチャすれば可能なのは可能なのですが、こんな風に画像を貼りけて移動するだけならば、Thumb コントロールに Template を配置したほうが手早くできます。

Thumb コントロール自体には背景が指定できないので、内部で Grid を作ってその中に Ellipse のような図形のコントロールを配置するのがミソですね。このあたり、もう少しゲームっぽい動きができたら、Windows Store app のサンプルに上げておきます。

実行するとこんな感じです。普通にタッチのドラッグで動きます。

これで、スライドゲームの準備ができたので「進めます」ってことで。

カテゴリー: C#, XAML, windows 8 パーマリンク