[win8] 動的にImageコントロールに画像を配置する

動的にタイル画像(スタート画面の画像)を DirectX で作成して、スタート画面に設定することはできたので、その調節中。
DirectX 自体は(多分)直接 C# から扱うことができないので、ライブラリを c++/cx で作成して c# から使うという手順になりそうです。
で、その前に、c++/cx 単体で動くことを確認中というところ。

眠るシーラカンスと水底のプログラマー ≫ Windows8 Metro:初めてのアプリはWindowsPhoneからの移植
http://coelacanth.heteml.jp/blog/?p=612

metro アプリケーションではファイルアクセスが基本、非同期になってしまったので、C# では非同期用の async/awit を使うことになりそうなのですが、c++/cx ではそれらしい文法追加がされていないので、task<> と lambda を駆使しないと駄目なんですよね~、これがちょっと厄介なのですが…これは別途。

で、まずは動的に作成したファイルを metro アプリ上で表示する簡単なチェックツールを作っていたのですが、ちょっとハマったので記録しておきます。

試しなのであらかじめ用意しておいた、logo.png, logo1.png, logo2.png のファイルを切り替えます。

プロジェクト構成はこんな感じで。Images フォルダ内に3つの画像ファイルを収めておきます。

■C# で画像を切り替える

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    string fname = (string)((Button)sender).Content;
    fname = "ms-appx:///Images/" + fname + ".png";
    BitmapImage bi = new BitmapImage(new Uri(fname));
    image1.Source = bi;
}

BitmapImage オブジェクトを作成して、Image コントロールに Source プロパティに設定、というところです。この場合は、アプリケーションリソースが対象なので「ms-appx://」となっていますが、アプリケーションのローカルに保存した場合には「ms-appdata://」を使います。このフォルダは、「C:\Users\<ユーザ名>\AppData\Local\Packages\<アプリID>\LocalState\」になります。まぁ、ここのアクセスは後ほど。

■C++/CX で画像を切り替える

WinRT のクラスだけを使っているので、C++/CX への変換は楽チンです。そのまま書き写すだけ。

void DynamicLoadImageCppCx::BlankPage::Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
	String^ fname = (String^)((Button^)sender)->Content;
	fname = "ms-appx:///Images/" + fname + ".png" ;
	Imaging::BitmapImage^ bi = ref new Imaging::BitmapImage( ref new Uri( fname ));
	this->image1->Source = bi ;
}

C# と同じように、BitmapImage オブジェクトを作成して Image コントロールの Source プロパティに設定という具合。namespace がちょっとややこしいので、「Imaging::BitmapImage」を使っていますが、正式名称は「Windows::UI::Xaml::Media::Imaging::BitmapImage」ですね。最初に「using namespace Windows::UI::Xaml::Media::Imaging;」としてしまっても ok です。

Windows Phone や Siverlight とは結構違うので、このあたりハマり処かもしれませんねぇ。ええ、DirectX を使うと更にハマってしまいそうな予感なのですが、そのあたりは後日。

ソースコードは github https://github.com/moonmile/win8/tree/master/DynamicLoadImage からどうぞ。

カテゴリー: C#, C++/CX, windows 8 パーマリンク