[win8] StorageFile の Open は、通常の Open/Close とちょっと違う

win8 本の執筆がてら、実験プログラムのメモ書き

古き良き時代から使われた C 言語の open/close の思考は、Windows ストア アプリの StorageFile に適用されるのかな?と思っていたの出すが、「違います」という話を少し。

■なんで違うのか?

端的に言うと、StorageFile クラスには Close メソッドがありません。ええ、C 言語の場合は open/close がワンセットになっているし、C# の場合は、StreamWriter/StreamReader でも Close しないといけないよ、というのがあるのですが、Windows ストア アプリの StorageFile クラスにはありません。Stream クラスにも Close がないし、StreamWriter クラスにも Close がありません。

なんじゃ、Flush というメソッドがあるから、それでいいじゃん、とも思っていたのですが、Flush は単にバッファのフラッシュをするだけ(ディスクに書き込みする)だけで、クローズとは違います。このあたりの落とし穴はまた後日書きますが…

■Close しないとどうなるのか?

Close メソッドがない StorageFile クラスですから、そもそもクローズを呼び出せません。
なので、ファイルが閉じられないのでは?と心配になるのですが、そのあたりは OS と StorageFile の間(実際は、Stream のところ?)でうまく調節をしているようです。

■実験コード

デザイナで、こんな画面をつくっておきます。

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Button 
        FontSize="24"
        Click="Button_Click_1"
        Content="ファイルに保存" HorizontalAlignment="Left" Margin="40,55,0,0" VerticalAlignment="Top" Height="99" Width="197"/>
    <Button 
        FontSize="24"
        Click="Button_Click_2"
        Content="ファイルから読込" HorizontalAlignment="Left" Margin="40,159,0,0" VerticalAlignment="Top" Height="99" Width="197"/>
    <TextBox 
        Name="text1"
        FontSize="24"            
        HorizontalAlignment="Left" Margin="268,55,0,0" TextWrapping="Wrap" 
        Text="ここにサンプルの文書を表示します。" 
        VerticalAlignment="Top" Height="429" Width="611"/>
</Grid>

ボタンのイベントはこちら


private StorageFile _file;
/// <summary>
/// ファイルピッカーで保存する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
	// FileSavePicker を用意する
	var picker = new FileSavePicker();
	picker.CommitButtonText = "データの保存先を指定する";
	picker.DefaultFileExtension = ".xml";
	picker.FileTypeChoices.Add("設定", new string[] { ".txt" });
	picker.SuggestedStartLocation = PickerLocationId.Desktop;
	picker.SuggestedFileName = "Sample.txt";
	// FileSavePicker を出して、ファイルを指定する。
	StorageFile file = await picker.PickSaveFileAsync();
	if (file == null)
	{
		// キャンセルされたときは何もしない
		return;
	}
	// ファイル名をデバッグ出力する
	Debug.WriteLine("保存先 {0}", file.Path);
	// 編集中の文章を保存する
	using (var stream = await file.OpenStreamForWriteAsync())
	{
		// サイズを0にしておく
		stream.SetLength(0);
		using (var writer = new StreamWriter(stream))
		{
			writer.Write(text1.Text);
		}
	}
	// 保存先のファイルをキープしておく
	_file = file;

}

/// <summary>
/// キープしている StorageFile を再利用する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
	// 保存先がないときは何もしない
	if (_file == null)
		return;

	StorageFile file = _file;
	using (var stream = await file.OpenStreamForReadAsync())
	{
		using (var reader = new StreamReader(stream))
		{
			text1.Text = reader.ReadToEnd();
		}
	}
}

文章をピッカーで保存しておいて、再び読み込むだけのプログラムです。メモ帳でありがちな「保存」ボタンの場合は、保存のほうで StorageFile を再利用するのですが、ここでは実験のために、読み込みのところで再利用をしています。

どうせクローズがないので using を使う必要もないのですが(Stream を破棄するために Dispose が必要なんですが)、まあつけておきます。Windows ストア アプリの場合、アプリ単位のサンドボックスになっている(はず)なので、多少リソースの解放を忘れても問題ないかと…乱暴ですが。

■実験1 PickSaveFileAsync 直後にファイルが作られる

if (file == null) でブレークポイントさせるとどうなるのか?ってのを試してみてください。
これ、別の実験のときに気づいたのですが、どうやら PickSaveFileAsync から戻ってきたときに「ファイルが作られます」。
このピッカーは、デスクトップに保存するようにしているので、デスクトップに「この時点」でファイルができます。
ちなみに、従来の Windows アプリ(デスクトップアプリ)の場合には、SaveFileDialog クラスを使いますが、ファイルは作られません…といいますか、SaveFileDialog は FileName プロパティで、ファイル名を取得するので、ファイル自体は作られないのです。

通常、Windows ストア アプリの場合、アプリのローカル フォルダー(LocalState フォルダー)にファイルを保存するので、さしても問題はないのですが、デスクトップとかスカイドライブとかにファイルを作成する場合には、この違いはちょっと注意が必要ですね。

■実験2 「保存」と「読み込み」の間にメモ帳で、Sample.txt を書き換えてみる

「保存」をしたときに StorageFile をキープして、「読み込み」のときに再利用しているわけですが…というか、アプリが続いている間はこういう再利用ができます。
ただし、アプリが中断したときは…と書こうと思って試してみると、中断→再開 をしても StorageFile オブジェクトはキープされていますね。これは後で調べておきましょう。

さて、
1.「保存」ボタンでテキストファイルに保存
2.メモ帳で、sample.txt を開いて内容を書き換える。
3.「読み込み」ボタンでテキストを読み込む

って手順をやると、途中の2で編集した結果が読み込めます。

なんとなく自然な感じがしますが(それはそれで「自然な感じがする」のは重要なのです)、よく考えるとちょっと不思議です。StorageFile クラスって、なにをキープしているのでしょうか?、そうなるとファイル名だけでもアクセスができるのでは?ってことですね。

■StorageFile クラスにはコンストラクタがない

実は StorageFile クラスにはコンストラクタがありません。

StorageFile class (Windows)
http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.storagefile(v=win.10).aspx

コンストラクタがないということは、なんらかの形でどこかのメソッドで作成してもらうわけけで、なんらかの「制限」がかけられている訳です。なんらかの「制限」ってのは、Windows ストア アプリが開けるファイルを OS 側(あるいはライブラリ側)が制限しているってことです。従来の SaveFileDialog クラスのようにファイル名を受け渡ししてから、StreamWriter クラスを使ってしまうと、どんなファイルでも開けるのですが、Windows ストア アプリでは、StreamWriter に渡すファイルオブジェクトは StorageFile に変更されているのです。
なるほど、そういうセキュリティなのね、という具合です。

■StreamWriter や TextWriter に Close がない理由

ここは想像ですが、ファイルに対しては非同期アクセスをするので(書き出し、読み出し自体は、同期メソッドが用意されているのですが、オープン自体が非同期なので)、クローズのタイミングを取るのはプログラム側では難しい、ってことなのかなと。
ただし、ここに落とし穴があって、C 言語タイプの open/close を想定していると、既存のファイルをオープンして書き出したときに不都合が生じるんですよね。いや、実際は不都合ではないのですが、OpenStreamForWriteAsync メソッドの仕様というところでしょうか。

	// 編集中の文章を保存する
	using (var stream = await file.OpenStreamForWriteAsync())
	{
		// サイズを0にしておく
		stream.SetLength(0);
		using (var writer = new StreamWriter(stream))
		{
			writer.Write(text1.Text);
		}
	}

なところで、ストリームのサイズを 0 に設定しておかないと、ファイルの書き出しが正常に行われません…というか、思ったように書き出せません。試しに stream.SetLength(0) のコメントアウトして、「文章の長さが縮まるように」してから保存してください。
保存したファイルを開くと、後ろに「ごみ」が残っているように見えます。
実は、OpenStreamForWriteAsync メソッドは、ランダムモードでオープンしている(たぶん)ので、ファイルが新規作成ではなくて、上書きになっているからなのです。

このあたり長くなるので、次の記事に続きます。

…と、ここまで書いて、いやいや「CreationCollisionOption」を付ければよいのでは?と気が付いた。後で修正。

カテゴリー: C#, windows 8 | [win8] StorageFile の Open は、通常の Open/Close とちょっと違う はコメントを受け付けていません

[win8] パンダ福笑いを作るために ManipulationDelta を使う

acer w500 のタブレットPC に windows 8 を入れて(これには元 winodws 7 が入っています)、子供に遊ばせようッ!!! っての第1弾

パンダ福笑い無料ダウンロード版 どうぶつ雑貨「パンダスプン」♪/ウェブリブログ
http://panda-spoon.at.webry.info/200803/article_5.html

からパンダのパーツを貰ってきて、下記なのを作ります。

目と耳、口のパーツは指を使って動かせるので、うちの2歳児でもできます。製作時間は、プログラミングに1時間弱(いろいろ調べたし orz)、パーツ切り取りに数時間です。どちらかというとパーツの切り取りが面倒だった、ってぐらいで、慣れるとこの手のドラッグ操作のものは簡単にできそうですね。

■画面を XAML で作る

<Grid Background="White">
    <Canvas x:Name="canvas" ManipulationDelta="el_ManipulationDelta">
        <Image Source="ms-appx:///panda/face.png" Canvas.Left="310" Canvas.Top="216" ></Image>
        <Image 
            ManipulationMode="All"
            Source="ms-appx:///panda/mouth.png"
            Canvas.Left="549" Canvas.Top="567" 
            />
        <Image 
            ManipulationMode="All"
            Source="panda/left_ear.png" Canvas.Left="310" Canvas.Top="239" >
        </Image>
        <Image 
            ManipulationMode="All"
            Source="panda/right_ear.png" Canvas.Left="663" Canvas.Top="172" ></Image>
        <Image 
            ManipulationMode="All"
            Source="panda/left_eye.png" Canvas.Left="455" Canvas.Top="429" ></Image>
        <Image 
            ManipulationMode="All"
            Source="panda/right_eye.png" Canvas.Left="646" Canvas.Top="366" ></Image>
    </Canvas>
</Grid>

ManipulationDelta のパターン ≪ 宇宙仮面の C# 研究室
http://uchukamen.wordpress.com/2012/08/16/manipulationdelta-%E3%81%AE%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3/
マルチタッチができるWindows 7アプリ作成の基礎 – @IT
http://www.atmarkit.co.jp/fwcr/design/ux/win7_01/01.html
ManipulationDelta を知ろう – 高橋 忍のブログ – Site Home – MSDN Blogs
http://blogs.msdn.com/b/shintak/archive/2012/05/01/10299351.aspx

マウスやタッチの移動をどうやって取得するか?なのですが、MouseMove は大変(つーか、タッチの場合は Mouse イベントは発生しません)、Thumb コントロールを使ったパターンも作ったのですが、そこそこ大変。で、ManipulationDelta イベントを取得するのが簡単ってことです。

# これ、WPF、Windows Phone にもあるので見落としていた模様 orz

画面は、Grid に直接配置するパターンがあるのですが、今回は Canvas を使っています。こっちのほうは xy 座標を直接指定できるので楽かなと。あとレイアウト変更に関係ないから描画が早いかも、っていう想像です。

ManipulationDelta イベント自体は、それぞれの Image コントロールに設定してもよいのですが、いくつか調べると、

  • コンテナ(Grid とか Canvas とか) ManipulationDelta イベントを設定する。
  • 動かしたい Image コントロールに ManipulationMode=”All” を設定する。

ってことで動きました。この例では、顔(face.png”)は動かさないようにするので、ManipulationMode を設定しません。

■ドラッグさせるコード

移動したとき ManipulationDelta イベントで、e.Delta を使うと、前回の移動からの差分が取得できます。絶対値がほしい場合は e.Position ですが、今回は使っていません。

/// <summary>
/// 移動中のイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void el_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var el = e.OriginalSource as UIElement;
    var img = el as Image;

    double x = Canvas.GetLeft(el) + e.Delta.Translation.X;
    double y = Canvas.GetTop(el) + e.Delta.Translation.Y;

    // 画面からはみ出ないようにする
    if (-img.ActualWidth / 2 <= x && x <= canvas.ActualWidth - img.ActualWidth / 2 &&
            -img.ActualHeight / 2 <= y && y <= canvas.ActualHeight - img.ActualHeight / 2)
    {
        Canvas.SetLeft(el, x);
        Canvas.SetTop(el, y);
    }
}

Grid を使う場合には img.Margin = new Thickness(…) とするのですが、Canvas の場合は Canvas.SetLeft と Canvas.SetTop を使います。
実際に指やマウスを使って動かすとわかるのですが、すーっと「慣性」が働いてどこかに行ってしまう(笑)ので、画面の端(実際には Canvas の端)で止まるようにしています。

■で、拡大と回転とかできないの?

早速、遊ばしてみるとうちの奥さんから「で、拡大とかはできないの?」っていう要求が…ええ、以前作っていた Thumb コントロールの場合その手のイベントを拾うのが大変そうだったのでやめていたのですが、ManipulationDelta であれば大丈夫そうですね。これは、後ほど実装をしましょう。

ってなわけで続く。

カテゴリー: C#, windows 8 | 1件のコメント

[win8] DefaultViewModel と DataContext は同時に使えない

昨日の続きで、気になるところをチェック。

もともと、WPF とか Silverlight では DataContext を使っていた…ような気がするので、じゃあ、Windows ストア アプリで登場した「DefaultViewModel」との違いは? とか、同時に使えるのか? ってところを試してみます。

ええ、結論から言えば「同時には使えません」。と言うか、おそらく DefaultViewModel のマップオブジェクトは内部動作として DataContext を使っているだろうから、同時には使えんのだろう、ってのが結論ですね。

■画面の準備

実験的に下記のような表を作っておきます。

<Grid HorizontalAlignment="Left" Height="243" Margin="32,38,0,0" Grid.Row="1" VerticalAlignment="Top" Width="727">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200"/>
        <ColumnDefinition Width="261*"/>
        <ColumnDefinition Width="266*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" FontSize="24" Margin="10" TextWrapping="Wrap" Text="ID"/>
    <TextBlock Grid.Row="1" FontSize="24" Margin="10" TextWrapping="Wrap" Text="Name"/>
    <TextBlock Grid.Row="2" FontSize="24" Margin="10" TextWrapping="Wrap" Text="Address"/>
    <TextBlock Grid.Row="3" FontSize="24" Margin="10" TextWrapping="Wrap" Text="Telephone"/>
    <!-- Buiding by DataContext -->
    <TextBlock 
        Text="{Binding ID}"
        Grid.Row="0" Grid.Column="1" FontSize="24" Margin="10" TextWrapping="Wrap"/>
    <TextBlock 
        Text="{Binding Name}"
        Grid.Row="1" Grid.Column="1" FontSize="24" Margin="10" TextWrapping="Wrap" />
    <TextBlock 
        Text="{Binding Address}"
        Grid.Row="2" Grid.Column="1" FontSize="24" Margin="10" TextWrapping="Wrap" />
    <TextBlock 
        Text="{Binding Telephone}"
        Grid.Row="3" Grid.Column="1" FontSize="24" Margin="10" TextWrapping="Wrap"/>

    <!-- Buiding by DefaultViewModel -->
    <TextBlock 
        Text="{Binding Item.ID}"
        Grid.Row="0" Grid.Column="2" FontSize="24" Margin="10" TextWrapping="Wrap"/>
    <TextBlock 
        Text="{Binding Item.Name}"
        Grid.Row="1" Grid.Column="2" FontSize="24" Margin="10" TextWrapping="Wrap" />
    <TextBlock 
        Text="{Binding Item.Address}"
        Grid.Row="2" Grid.Column="2" FontSize="24" Margin="10" TextWrapping="Wrap" />
    <TextBlock 
        Text="{Binding Item.Telephone}"
        Grid.Row="3" Grid.Column="2" FontSize="24" Margin="10" TextWrapping="Wrap"/>
</Grid>

何をやっているかというと、左に DataContext でのバインディング、右に DefaultViewModel でのバインディングの表を作っているだけです。

■実験コード

  • DataContext だけで設定するパターン
  • DefaultViewModel をだけで使うパターン
  • 両方を使うパターン

の3つを用意しておきます。

/// <summary>
/// DataContext に設定する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void clickDataContext(object sender, RoutedEventArgs e)
{
    var item = new DataModel()
    {
        ID = 10,
        Name = "masuda",
        Address = "Tokyo",
        Telephone = "03-0000-0000"
    };
    this.DataContext = item;

}

/// <summary>
/// DefaultViewModel に設定する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void clickDefaultViewModel(object sender, RoutedEventArgs e)
{
    var item = new DataModel()
    {
        ID = 10,
        Name = "tomoaki",
        Address = "Osaka",
        Telephone = "06-1111-0000"
    };
    this.DefaultViewModel["Item"] = item;
}

/// <summary>
/// 両方で設定する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void clickDual(object sender, RoutedEventArgs e)
{
    var item1 = new DataModel()
    {
        ID = 10,
        Name = "masuda",
        Address = "Tokyo",
        Telephone = "03-0000-0000"
    };
    var item2 = new DataModel()
    {
        ID = 10,
        Name = "tomoaki",
        Address = "Osaka",
        Telephone = "06-1111-0000"
    };
    this.DataContext = item1;
    this.DefaultViewModel["Item"] = item2;

}

さて、これで Dual ボタンをクリックするとどうなるのか?両方にうまく表示されるのか?というと、実は違って、DataContext のほうだけが表示されます。

なんか不思議ですが「DataContext」と「DefaultViewModel」のボタンを交互に押すと、「DataContext」のほうしか残りません。つーか、おそらく DefaultViewModel のほうは上書きされちゃったのでしょう。
なので、うっかり DataContext を使ったコードを流用すると、新しい DefaultViewModel を使ったものが動かなくなる、っていう「落とし穴」がありますね。まあ、どちらか片方の方式で統一するということで。

ちなみに、DataContext のほうは、オブジェクトを渡して内部のプロパティ名を Binding するので、複数のオブジェクトをバインディングすることができないという罠があります。コンテキストをひとつの DataModel としてまとめられればいいのですが、画面によっては複数のオブジェクトを割り付けたい場合は多々あります。
なので、DefaultViewModel のように、複数のオブジェクト(Item オブジェクトと SubItem オブジェクトとか)を渡せるのは、改善なんでしょう、やっぱり。

カテゴリー: C#, windows 8 | [win8] DefaultViewModel と DataContext は同時に使えない はコメントを受け付けていません

[Win8] ひとつだけのデータバインドを metro アプリではどう実装するのか?

ちょっとメモ書き的に。

metro アプリでは、XAML を使ってデータバインディング、ってのが主流?なのですが、プロジェクトテンプレートを見ると、GridView とか FlipView とかの「コレクション」に対するバインディングは多いのですが、ひとつのアイテムだけをバインディング、っていう簡単な手法が示されていない…んですよね。たぶん。見つけ方が悪いだけなのかな?

ここのところ、MVVM パターンのほうはさておき、実装的にどうすれば「教えやすいのか?」ってのを考えると、
コードを使ってちまちまとコントロールの Text プロパティやらに設定していく、ってのが一番安全な方法だと思うわけです。で、まあ、それでも良いのですが、せっかく MVVM パターンのテンプレートを使っているわけだし、それなりのバインディング用のクラス「BindableBase」があるわけで、これを活用しようかな、と悩んでいたわけですが。

■モデルクラスを作る

namespace SampleDataBinding.DataModel
{
    class MainItemSource : BindableBase
    {
        private int _id;
        public int ID {
            get { return this._id ; }
            set { this.SetProperty(ref this._id, value); }
        }

        private string _name ;
        public string Name {
            get { return this._name; }
            set { this.SetProperty(ref this._name, value); }
        }

        private string _address ;
        public string Address {
            get { return this._address; }
            set { this.SetProperty(ref this._address, value); }
        }

        public override string ToString()
        {
            return string.Format("{0}:{1}", this._id, _name);
        }
    }
}

ひとつの Model がひとつの View に対応するという一番単純な例です。この単純さだと、Text プロパティにちまちまでもいいのです
「基本ページ」などでインポートされる、BindableBase クラスを継承してモデルクラスを作ります。コレクションに利用するのではなくて、が、バインディングの練習がてらに。

■リソース経由で参照させるパターン

以前から使われているリソースから直接渡すパターンです…と思います。
「xmlns:model=”using:SampleDataBinding.DataModel”」という名前空間をあらかじめ指定しておいて、スタティックリソースに「DataSource」という名前をつけます。MainItemSource クラスを直接参照できるので、便利といえば便利なのですが。

    <Page.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">My Application</x:String>
        <model:MainItemSource x:Key="DataSource" />
    </Page.Resources>

下のように、Source=”{StaticResource DataSource}” が必要になります。デフォルトのデータソースを指定できたような気もするのですが、ちょっと忘れてしまいました

<TextBlock x:Name="labelID" 
     Text="{Binding ID, Source={StaticResource DataSource}}"
     HorizontalAlignment="Left" Margin="272,73,0,0" Grid.Row="1" 
	TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" Height="29">
 </TextBlock>
 <TextBlock x:Name="labelName"
     Text="{Binding Name, Source={StaticResource DataSource}}"
     HorizontalAlignment="Left" Margin="272,123,0,0" Grid.Row="1" 
	TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>

ここで問題なのは、MainItemSource のオブジェクトってどこでで作成されているんだろうか?というのと、いったい、ID とか Name とかはどこで設定すればよいのか? ってことなのです。業務的には、よくわからないから、いきおい MainItemSource クラスを変更して static であらかじめ初期値を入れておいたり、ってことになるわけですが、それはちょっとあんまりなコードですよね。

…と、ここまで書いて思い出しました。View に DataContext というプロパティがありました。
XAML のほうを、次のようにバインディングする ID や Name プロパティ名を指定しておきます。

<TextBlock x:Name="labelID" 
     Text="{Binding ID}"
     HorizontalAlignment="Left" Margin="272,73,0,0" Grid.Row="1" 
	TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" Height="29">
 </TextBlock>
 <TextBlock x:Name="labelName"
     Text="{Binding Name}"
     HorizontalAlignment="Left" Margin="272,123,0,0" Grid.Row="1" 
	TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>

でもって、コードのほうで

protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
    var item = new MainItemSource()
    {
        ID = 10,
        Name = "masuda",
        Address = "Tokyo"
    };
    this.DataContext = item;
}

という形で MainItemSource オブジェクトを設定しておけばよいわけです。なるほど、これで十分動きます。

■DefaultViewModel を使う

そんなわけで、もうひとつの方法を。
XAML をもういちど見ていくと、

<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="SampleDataBinding.BasicPage1"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

DataContext なところがあります。いくつか解説もあるのですが、要するに PHP 風や、ASP.NET の ViewState 風に画面のほうにデータを引き渡せる手段です。

Windowsストアアプリにおける グリッドアプリケーションについて(1) – 荒井省三のBlog – Site Home – MSDN Blogs
http://blogs.msdn.com/b/shozoa/archive/2012/10/18/about-grid-application-1-on-windows-store-application.aspx

下記のように、DefaultViewModel[“Item”] を使って「Item」という名前をつけておくと、

protected override void LoadState(Object navigationParameter, Dictionary pageState)
{
    var item = new MainItemSource()
    {
        ID = 10,
        Name = "masuda",
        Address = "Tokyo"
    };
    this.DefaultViewModel["Item"] = item;
}

こんな風に「Item.ID」とか「Item.Name」とかで MainItemSource オブジェクトの中身が参照できます。

<TextBlock x:Name="labelID" 
    Text="{Binding Item.ID}"
    HorizontalAlignment="Left" Margin="272,73,0,0" Grid.Row="1" 
    TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" Height="29">
</TextBlock>
<TextBlock x:Name="labelName"
    Text="{Binding Item.Name}"
    HorizontalAlignment="Left" Margin="272,123,0,0" 
    Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>

なるほど、こっちのほうがわかりやすい気がします。

ちなみに、ボタンを配置して、

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    _item.Name = "masuda tomoaki";
}

のように、Name プロパティの値を変更すると、画面の表示も変わります。MainItemSource クラスの SetProperty が効いているということですね。
そんなわけで、DefaultViewModel を使うほうが、直感的でわかりやすいかなと。まあ、バインディング自体を XAML に記述するところがアレですが、ひとまずこれで。

カテゴリー: C#, windows 8 | 1件のコメント

フューチャーワークス カンファレンスを開催します

来る 12/1(土) 13時半から「フューチャーワークス カンファレンス」開催します。
場所は「日本工学院八王子専門学校」です。

image

主催は増田(moonmile)個人ですが(笑)、手弁当でプレゼントなぞ用意します。

Professional Programmer’s Club
http://pp-club.net/

PP-Club の活動(?)の一環として、啓蒙…でもないのですが、やる気のある学生さんプログラマや新人プログラマの「やる気を削がない」と、その先に「何をしたらいいのか?」ってことをお話します。話自体は、一般的な技術論とかマネージメントとかではなくて、「自分が現実に今やっていることがら」が中心になりますので、それぞれの「現場」の雰囲気がわかると思います。IT 業界って、ゲーム業界とか組み込み系やら情報系やらサーバー管理やら、なにやらといっぱいあって実は「選択肢は広いッ!!!」ってことです。

スピーカーは、

・Lonnie&Associates株式会社 高橋さん
・株式会社イーオス21 CEO 鈴木さん
・片柳学園 サーバ管理者 水庭さん
・ワタクシ 増田

です。

当日は、

・PP-Club ロゴ入りのクリアファイルを参加者全員にッ!!!
・抽選で、増田著作の「逆引き本」「ひと目本」を数名様にッ!!!
・抽選で、iPad mini 1名様にッ!!!

今回は、はじめての開催ということでプレゼントは多少「豪華め」に用意いたしました。ええ、手弁当なもので、そのあたりは察していただければよいかと(苦笑)。

参加申し込みは <a href=”http://pp-club.net/”>こちら</a> 「参加受付中」あたりをクリックして進んでください。

カンファレンス終了後には、八王子駅あたりで「懇親会」(単なる打ち上げとも言う)を予定していますので、ぜひ参加してください。学生の方は、いわゆる「後輩価格」にする予定です(まあ、人数と私の懐具合にもよりので、そのあたりは大人の判断で)。

ぼちぼち、無料プレスを発射しますので、そのあたりも参考にしていただければよいかと思います。

カテゴリー: PP-Club | フューチャーワークス カンファレンスを開催します はコメントを受け付けていません

学生向けカンファレンスをやります

1週間ほど死ぬ気で仕事をしておりましたが、やっと持ち直してきたので告知します。いや、単に死ぬ気でやるよりも、「楽しんで仕事をやろうッ!!!」ってのがワタクシの趣旨だったことを思い出したわけで。

とある八王子な場所で、学生向けカンファレンス(とはいえ、社会人もOKです)をやります。

とある「87 Clockers」監修な方、およびワタクシ、かつ諸々で手弁当で講演などをさせていただきます。手弁当なもので、なんらかの形で「手弁当」をしようかなと思っているのですが、予定としては、

  • (いらないかもしれないけど)資料を配布するためのクリアファイルを、参加者全員に
  • 「87 CLOCKERS」を(可能ならば)サイン本で、数名に
  • ワタクシの著書を(希望があればサインして)、数名に
  • iPad mini を抽選で1名様にッ!!!

ってのを考えているのですが、どうでせうか?

本格的な告知は、数日後に  http://pp-club.net/ で行いますので、ご期待ください。

カテゴリー: 雑談, PP-Club, 勉強会 | 学生向けカンファレンスをやります はコメントを受け付けていません

企業アカウントの Windows ストアアプリの発行者名を変更する

さて、Windows Store の正規版もでてきたので、ぼちぼち(今更ながら)「有料アプリでも」と思っているわけですが、ちょっと気がかりなところ Windows ストアアプリの発行名のところです。

image

アプリをダウンロードする際に「発行者」のところを見るパターンが多い訳で(この場合は「TUTAYA.com Co.,Ltd」が発行者名)、この部分は慎重に考えてないと駄目なのです。

個人アカウントの場合は、発行者名は他とダブらない限り大丈夫なのですが、企業アカウントの場合は、「発行者名」と、シマンテックで審査する「登録名」(大抵は法人登録名)が異なると駄目なのです。
ここ、かなり問題があるので一応指摘しておくと、Windows ストアの発行者名は、システム的にダブりがあるかどうかをチェックしているだけなので、ひょっとすると「Microsoft」とか「Apple」とかの名前が通る可能性があります。まあ、大企業名を個人アカウントで付けると、問題が発生するのでそのあたりは常識の範囲内で、ということなるのですが、国が違えば「企業名が同じ」可能性もあり、業種が違えば「登録名が同じになる」可能性は高くなります … そのあたり、ダブってしまった場合はどういう審査をするんでしょう?

ひとまず、個人事業主の場合は「屋号」としての一致を確認するとのことなので、このあたりの変更を日本シマンテックに質問をすると、

登録社名を「Moonmile Solutions」にご変更をされますと、認証審査を「Moonmile Solutions」にて新たに行う必要がございますので、「Moonmile Solutions」で企業登録が確認できない場合につきましては、認証審査を完了することができませんので、ご了承ください。

弊社では認証審査のみを行っておりますので、ブランド名の変更につきましては、大変お手数ですが、マイクロソフトにご相談いただきますよう、お願い申し上げます。

って、ことで「日本シマンテック」は審査しかやってないので、発行者名を屋号と異なるようにしたい場合は、マイクロソフトに質問してくださいという回答を得ました。

で、マイクロソフトさんに質問をすると、

発行者名使用の可否は第三者機関であるシマンテック社に委託されており、弊社ではお答えできかねます。

弊社は発行者名がすでに使われていないかの最低限の重複チェックをシステム的に行っておりますが、審査の大半はシマンテック社が行っており、またそのプロセスや審査基準は公平性を期すため非公開となっているため、弊社が発行者名の使用を許可したとしても、シマンテック社が審査段階で拒否すれば、その発行者名をお使いになることはできません。

恐れ入りますが、シマンテック社の方へご相談いただけますよう、よろしくお願い致します。

なお、企業ではなく個人の開発者であれば、第三者が法的な権利を持っている場合などを除き、そういった制約はございません。

って、ことでにシマンテック社に依頼してるものなので、審査では答えられませんと変えてきます。

詰んでますね … これは。

結論を云えば、「屋号」と一致しない登録者名は企業アカウントでは使えない、ってことですね。

なので、なんらかの書類がない限り、発行者名を屋号と異なるように設定することは難しいので、

  • 屋号を「マイマイカンパニー」から「MyMy Company」に変える
    → カタカナをアルファベットにするのは OK ではないかと(英語、表記名ということで)
  • 税務署に「MyMy Company」の屋号変更をしてから、シマンテックに提出する。
    → これは税務署のほうが通らない可能性がある。

なので、いきなり「マイマイカンパニー」という登録名をブランド名としての「Monnmile Solutions」に変えるのは危うそうなので(審査に時間がかかるとか)、ちょっと、アルファベットの表記名で OK かどうか問い合わせをしてみましょう。

カテゴリー: 仕事, windows 8 | 企業アカウントの Windows ストアアプリの発行者名を変更する はコメントを受け付けていません

アプリを販売するために税務プロファイルを通す(個人事業主編)

Windows ストアでアプリを販売するためには「税務プロファイル」というのを通す必要があります。ここで難関(でもなかった?)なのは、W-8BEN フォームという、源泉徴収の場所をアメリカではなくて日本で行う(なのかな?)書類を提出します。

W-8 フォームへ記入後の署名方法
http://social.msdn.microsoft.com/Forums/ja-JP/winstoreapp/thread/b10acdce-30ea-48ce-87e4-9c03c616db91

Windows ストアからの支払いの受け取り – Windows Store 開発者向けブログ – Site Home – MSDN Blogs
http://blogs.msdn.com/b/windowsstore_ja/archive/2012/08/08/recevoir-les-paiements-du-windows-160-store.aspx

W-8BENフォームの記入方法(書き方)
http://www.option-dojo.com/st/w-8ben.html

 

提出とはいえ、Windows ストアの場合はフォームに入力して、そのまま「送信」とするだけです。Apple の場合とか FX の場合は FAX を使うとか色々あるみたいなのですが、まあ、それなりに簡単かと。審査時間は、非常に短くて1時間で終了(日本時間午前9時に提出して、同日午前10時には審査が完了していました)。まあ、それでもアメリカの1営業日はみておいたほうがよいかも。

さて、個人事業主&企業アカウントの場合、ちょっとややこしいのですが、いわゆる「企業」として出してください、との MS サポートからの返答を貰いました。

企業アカウント&個人事業主で登録している場合、
税務プロファイルの登録時に、「受益権所有者 (Beneficial Owner) の選択」のページで
「はい、私は個人の受益権所有者であり、このアカウントで生じる所得を直接受け取ります。」
が選択できません。
日本の「個人事業主」の場合は、どうしたらよいのでしょうか?
登録IDは、以下となります。(略)

という質問をしたところ、

企業アカウントとして開設された場合は、システム上、個人としての選択肢が無効となりますので、企業としてご提出いただく必要がございます。

という回答を得たので「企業」として提出を続けます。

プロファイルの「税」のところをクリックして、税フォームを入力していきます。

image

日本からなので「米国以外」ですね。

image

ここで「個人事業主」なので、個人を選択したいところですが、チェックができません。システム上、そうなっているということなので「企業」として「受益権所有者である事業体の代理」ってことにします。まあ、代理でも本人でもどうでもいいので。

image

日本から(アメリカ以外)からなので、W-8BEN の書類を提出します。これは、AppleHub とか FX とかで使うものと同じです。ってことで、「W-8BEN」で検索をするといくつか作例がでてきます。

image

「Type of beneficial owner」のところで「Invividual(個人)」を選択したいところですが、企業アカウントなので選択できません。ここは「Corpration(企業)」ってことにしておきます。代理人の書名なんかがありますが、「CEO」を選択して OK です。個人事業主は「事業主」ですからね、嘘ではありません。

で、これを入力したあとに「送信」をすると、しばらくたって PDF ができあがります。この PDF は、自分の保管用なので、どこかに保存しておくとよいでしょう。審査自体は「送信」ボタンを押した時から進むようで、私の場合、1時間後に再び税務プロファイルを見てみると、

image

ってことで、無事「企業アカウント」を使って「アプリの販売」の準備ができました。

カテゴリー: 仕事, windows 8 | アプリを販売するために税務プロファイルを通す(個人事業主編) はコメントを受け付けていません

Windows Store で企業アカウントを取得する(個人事業主編)

Windows Store で、「個人」でアカウントを取るときは、素直に「個人アカウント」で取ったほうが楽なのでしょうが、ビジネス的に「企業アカウント」を取ってみます … って、企業アカウントとは取れたけど、まだ「課金」のほうは問い合わせ中なので。

Windows ストア用 Microsoft アカウントの選択
http://msdn.microsoft.com/ja-jp/library/windows/apps/hh868187.aspx

アプリの販売
http://msdn.microsoft.com/ja-jp/library/windows/apps/br230836.aspx

■「企業アカウント」を選択する

Windows ストアは、Windows Live ID に結び付けられているので、最初に Windows Live ID を取得します。企業アカウントは、この Windows Live ID に結びつけられるのですが … これって、開発者が多い企業(大企業)でやり始めると、アプリ登録が難しくなるような気もするのですが、まあ、それは良しとして「企業アカウント」を選択します。

image

こんな風に企業アカウントだと「デスクトップ アプリケーションをストアに提出できる」ってのがメリットですね。

さて、ここの表示で問題なのは「発行者情報」と「承認者情報」です。この前提として、

  • 発行者は、アプリの開発/登録者本人(だけど企業に1名)で、メールアドレスが必要
  • 承認者は、発行者の上司で、作業を承認する人で、メールアドレスが必要

という形式になっています。個人事業主の場合、発行者=承認者(自分で自分を承認する?)という方法になるので、このメールアドレスはひとつになるハズなのですが、「同じメールアドレスは登録できません」。で、仕方がないので、最初は、適当な2つのメールアドレスを使います。

発行者情報にある「発行者の表示名」ですが、このブログのように最初は「moonmile solutions」を指定しました。

で、登録完了して、しばらく待つ(1日ぐらいか?)と、シマンテックからメールが来ます。

■個人事業主を証明するための書類

MS Marketplace – JP ということころからメールが来ます。内実は、マイクロソフト社から認証を委託された日本シマンテックです(他の国の場合は、それぞれの委託機関があると思われます)。

発行者 ID の申請を処理するにあたり、御社の登記簿謄本(公益法人の場合は設立許可証)を以て御社の所在を確認し ID の発行を認証いたします。

ということなので、株式会社の企業の場合は「登記簿謄本」を用意します。書類は PDF で送るようになるっているので、登記簿のスキャンで良いと思われます。現在地と会社名の確認になりますね。

ですが、「個人事業主」の場合には、登記簿というのが存在しないので、問合せをしました。

*「個人事業主」の場合は 「個人事業の開廃業等届出書」を税務署あてご提出いただいていると思いますので、そのコピーを添付ファイルとして、お送りいただけますでしょうか?(ファイル名は必ず半角英数文字にて御願いいたします。)

という回答が来たので、「個人事業の開廃業等届出書」で良いようです。これは、個人で確定申告を出す時に使う書類で、自分で税務処理をするときに使います。実は、会社員でも出すことができます。なので、いち会社員でも企業アカウントは取ることができそうですね。

あと発行者と承認者のメールアドレス&名前の件も、問い合わせてみました。

申請担当者、責任者が同一人物であることは、問題ございません。

とのことで、個人事業主の場合は、ひとつのメールアドレスで OK です。ただし、

Domainが企業登録、または増田様が登録者となっているもの

ということになっているのが、多少厄介です。私の場合、幸いにして moonmile.net 等ドメインをもっているのですが、これがないと Windows ストアアプリが作れないのはちょっと辛いです。個人商店のような場合には、独自ドメイン&独自メールアドレスを持っていない場合が多いので、企業アカウントの「認証」が通りません。まあ、その場合は「個人アカウント」にしよう、ってことでしょうか。

という訳で、本棚の奥にあった

  • 個人事業の開廃業等届出書

を引っ張り出して、スキャンをして日本シマンテックに送ります。

■屋号と登録者名/発行者名が一致しないと駄目

書類を出したので、認証審査が通ると思いきや、再び MS Marketplace – JP からメールが来ます。

屋号:マイマイカンパニーとなっておりますが、この場合、現在ご登録の「Moonmile Solutions」という御名前との認証ができません。登録名をご変更いただく必要がございます。

ええ、個人事業の開廃業等届出書を出したのは 5 年以上前なのですが、通称名は色々と変えているんですよね。現在のところ名刺には「Moonmile Solutions」になっています。税務署の確定申告は「マイマイカンパニー」で届くんですよね。実は、この屋号の欄は、提出する税務署によっては「空欄」でも OK なので、この縛りはきつすぎるかなぁ、と思っています。ちなみに、屋号は後から変更できますので、開廃業等届を再提出すると、この「屋号」の欄をマッチさせることができます。

image

ここの「発行者」のところに、屋号が表示されるハズなんですけどね。

が、まあ今回は税務署に行く暇もないので、「マイマイカンパニー」で通して貰うことにしました。発行者名は、後から変更できるようです。ただし、

登録社名を「Moonmile Solutions」にご変更をされますと、認証審査を「Moonmile Solutions」にて新たに行う必要がございますので、「Moonmile Solutions」で企業登録が確認できない場合につきましては、認証審査を完了することができませんので、ご了承ください。

弊社では認証審査のみを行っておりますので、ブランド名の変更につきましては、大変お手数ですが、マイクロソフトにご相談いただきますよう、お願い申し上げます。

となっているので、再度、日本シマンテックの審査が必要になります。となると、屋号に再び引っ掛かるので、先に税務署に行って屋号を変更しておくのが無難かと。

後で、マイクロソフト社には問い合わせをしますが、発行者名を「屋号とは異なる名前」に変更できるか、聞いてみます。この「発行者名」は、Windows ストアアプリを表示するときにも使われるので、「アルファベットでないと、英語圏で表示できないのでは?」と思われるためです。このあたり、日本で登録する(英語圏以外で登録する)ときの弊害ですね。

image

■承認者に承認せよとのメールが来る

Symantec (シマンテック) は、マイクロソフトから所在確認および認証業務を委託された第三者機関で、Microsoft Developer Services の発行者 ID 申請時に提出された各種情報を検証し ID 発行の認証を行います

というメールが「承認者」に来ます。これを通さないと、発行者が「アプリの発行」ができないので、なかなかメールを見ない上司を承認者に据えてしまうと、ちょっと問題ありかも。まあ、情報系の上司だったら大丈夫でしょう。私の場合は、個人事業主なので自分で自分を承認する、という作業になります。

■受け取りアカウントを設定する

認証の審査が通ったので、受け取りアカウントを設定します。

# 無料アプリのみの場合は、これは必要ないんですかね?

クレジットカード経由で振込みが行われるらしく、

  • クレジットカードの明細書(Microsoft からの請求)
  • クレジットカード引き落としの銀行口座

が必要になります。私の場合、セゾンクレジットカード、三菱東京UFJ なので、ネットから明細書が見られてよかったのですが、他のクレジットカード、銀行口座の場合は結構手間かもしれません。特に、Microsoft からの請求書に入っているコードを入力しないと、この部分が通らないので、「明細書」がないと受け取りアカウントが作れない、というジレンマがあります。明細書って通常、2か月後ぐらいにくるから、ひどく遅くなるんですけど…。

幸いにして、セゾンクレジットカードの場合は、請求予定の明細書をネット上で見れるサービスがあるので大丈夫なのですが、このあたり、非常に手間です。また、受け取りアカウントの銀行口座には、いくつか制限があるようです。SWIFT コードを入力しないといけないのですが、これがない場合はどうするのでしょうか?多分だめ?

ちなみに、三菱東京UFJ は「BOTKJPJT」になります。

日本の金融機関のSWIFTコード一覧 – Wikipedia
http://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E3%81%AE%E9%87%91%E8%9E%8D%E6%A9%9F%E9%96%A2%E3%81%AESWIFT%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7

image

このあたりを登録すると、はれて「無料アプリ」を公開できる段階になります。

さらに、アプリを販売するためには「税務プロファイル」ってのが必要なんですよね。このあたりは、現在問合せ中なので、しばしお待ちを。

~~~

アプリの販売の場合、

  • Windows Store を提供する Microsoft の取り分
  • 源泉徴収税

ってのが必要になります。この源泉徴収税が、日本から米国に申請をすると 30% という高い金額(日本国内の場合は 10% … でも外国からだと高い?)なので、減税処置を考えるならば、なんらかの方策が必要ですよね。アプリ単体売りではなくて、無料アプリを配布して広告収入なり独自課金なりを考えるのがベターかと。まあ、本格的にやるならば米国内に法人化なんでしょうけど。

image

カテゴリー: 仕事, windows 8 | 2件のコメント

【募集】 iPhoneアプリ初心者本のお手伝い募集中

ブログで募集します。

某社で iPhone アプリ初心者本を書いているのですが、私(増田)のお手伝いさんを1名募集します。

■主な仕事

  • サンプルアプリのデザイン直し。サンプル自体は増田が作成します。
  • 画面キャプチャ全般
  • ヒントかコラムをいくつか、あとは校正などの手伝い

■条件

フリーでも会社員でも構わないのですが、できればフリーの方。。iPhone/iPad 関係では、ミニゲームライブラリ販売計画と高速電子書籍計画が進行中です。まあ、書籍ネタにぼちぼちと、其の後の企画を混ぜるという私のスタイルですね。

年齢、性別は問いません。実力はちょっとは問うかも(iPhoneプログラミング初心者でもよいのですが、なんらかのプログラミングができることが条件です)。

当然ながら、iPhone, Mac を持っていることが前提条件です。実機で動かすために iOS ライセンスがあれば吉なのですが、ない場合は1年分当方が登録します。

■金額

金額的には、10万から5万円の範囲で。作業量を決めて責任を負っていただければ10万で、ちょっと時間的に責任が持てない(会社員とか他の仕事がある場合とか)場合は5万円とか、という要相談という形にしたいと思います。

■応募方法

お問い合わせ | Moonmile Solutions Blog
http://www.moonmile.net/blog/contact

のフォームに「iPhoneアプリ手伝い応募」とタイトルを書いて、応募してください。折り返し質問などのシートを送ります。

また、質問があれば、この記事のコメントに書くか、先のお問い合わせのフォームから質問してください。

カテゴリー: 仕事, Objective-C | 【募集】 iPhoneアプリ初心者本のお手伝い募集中 はコメントを受け付けていません