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

list このエントリーをはてなブックマークに追加

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

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

    </Grid>
</Page>

▼MainPage.xaml.cs

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

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

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


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

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

    /// <summary>
    /// ドラック中
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></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 パーマリンク