2011-12-22
Silverlightで適当なアプリを作ってわかったこととか。
技術, Silverlight | | ![]()
やりたいと思ったけどできないことにいろいろぶつかったので、備忘録的にここに記す。
MVVMとか
データアクセスもしないのでコードビハインドにべったり書いてしまったけど、今時のSilverlightのお作法にはまったく従っていない。残念です。
日付の選択支援
コミケの開催日だけ選択できるような仕組みにできればと考えたけど、マスターがどこにもない。開催日が公開されたらいちいちアプリを更新するしかなさそうだ。
依存プロパティとデータバインド
入力部のテキストボックス等の入力に合わせて、荷札部分のテキストブロックを更新させたい。
イベントハンドラを書くのかと思ったら、バインディングを記述するだけで実装できた。すげえ。
Text="{Binding (参照するプロパティ), ElementName=(参照先の部品のID)}"
これだけで勝手に更新されてくれる。
Comboboxの背景色
洗濯されたComboBoxItemの背景色がComboBoxそのものにも反映されるかと思ったんだけど、なんか灰色のグラデーションがかかっているおかげで色が全然目立たない。
グラデーションだけでも解除できればと思ったけど、デフォルトのレイアウトを変更するにはExpression Blendを使う以外に現実的な方法がないらしく、買ってない自分には手も足も出ない。
Comboboxへのデータバインド
バインドする際にComboBoxItemの背景色まで設定させたかったんだけど、どうしてもできなかった。
DataTemplateを持たせて中身にStackPanelを配置し、その背景色をバインドさせることはできたけど、見た目が通常のComboBoxと同じにならないのでダメだった。
結局現状はハードコーディングです。しょぼいのう。
DatePickerのガイド文字列
DatePickerのガイド表示(Watermark)は簡単には変更できない。サブクラス作るしかないんだって。すごい邪魔なんだけど……
http://coelacanth.heteml.jp/site/silverlight/article_10
JSONの扱い
JSON文字列を扱うためにSystem.Jsonという名前空間をusingする。
参照設定どれよ、と思ったらSystem.JsonというDLLがあった。
印刷時の解像度
Silverlightから印刷する際の解像度は96dpiで固定とのこと。この記事を見て初めて知った。
http://msdn.microsoft.com/ja-jp/magazine/hh148152.aspx
http://code.msdn.microsoft.com/10-C-034ee139
というわけで、B6のサイズはタテ128mm*ヨコ182mm。1inch=25.4mmなので、25.4で割って96をかければピクセル数が出る。
元のUIElementの縦横の幅をActualHeight/ActualWidthで取り出し、このピクセル数を割って倍率を出す。この倍率でScaleTransformを使って拡大して印刷すればok。
UIElementを画像ファイルに書き出す
WriteableBitmapクラスを使うと、UIElementをビットマップ型に書き出すことができる。
第2引数にTransformを渡すことで、出力に変形を加えることもできる。
WriteableBitmapをJPEGに変換する方法はこちらを参照した。FluxJpegというライブラリを使用する。
http://d.hatena.ne.jp/ksasao/20100719/1279550667
UIElementのコピー
印刷する際にPrintDocumentにUIElementを渡せば、配下のコントロールごと出力してくれる。
ただ紙幅に合わせてScaleTransformを使って印刷対象のUIElementを拡大してみると、印刷後も画面上で拡大されて見えてしまう。
理想としては、印刷対象のUIElementをコピーしてそれをRenderTransformで拡大し、印刷し終わったら捨てるようにしたい。
でもXAML上のUIElementをコピーする方法がわからない。
WPFならXamlWriterでUIElementのXAML表記を取り出せるけど、Silverlightにはない。
子コントロールと属性を一つずつ手動でコピーする
http://eightyeightpercentnerd.blogspot.com/2008/03/silverlight-cloning-xaml-element.html
リフレクションを使う
どっちも微妙だな!
あきらめて印刷時もWriteableBitmapでビットマップを取り出すようにしたよ。(WriteableBitmapのコンストラクタにtransformを与える場合、元のUIElementは影響を受けない。)