前回
WPFとVB.NETでDataContextやBinding、INotifyPropertyChangedの練習 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14088361.html
の続き
前回のアプリに今の状態をファイルに保存する機能とそのファイルを読み込む機能をつけた、名前を付けて保存とファイルを開く、ゲームで言えばセーブとロード
表示した二つの画像の縦横回転角度をスライダーとボタンで変更
前回と違うのはBorderから実際の画像ファイルをImageに表示したのと
回転角度を変更できるようになったところ
セーブとロード
状態の保存(セーブ)
ここではsave1にした
保存したファイルを開く
アプリを再起動で初期状態に戻す
デザイン画面とXAML
VBコード
またヤフーブログの文字数制限に引っかかったのでコード部分も画像だけ…
セーブファイルはZip形式で保存するので準備として
System.IO.Compressionを参照に追加しておく
方法は
WPFとVB.NETでデータをシリアライズしてZipファイルに保存 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14077359.html
縦横、回転角度を入れておくクラスSaveData
クラスの宣言の頭にSerializableを付けて(230行目)これで良しと実行してみたら
SerializationException はハンドルされませんでした。
'System.ComponentModel.PropertyChangedEventManager' はシリアル化可能として設定されていません。
っていうエラーが出た
エラーの内容を見るとPropertyChangedってあるからそれっぽい
Public Event PropertyChangedにシリアライズしません!属性のNonSerializedをつけたら、うまく行った(234行目)けどよくわからん
MainWindow
BitmapSource、SaveData、Imageを入れておくリストが3つ
リストはObservableCollectionも使っているけど、普通のListでもいいのかも
アプリ起動時に実行するinitial
Imageを作成してリストに追加
SaveDataを作成してリストに追加
Imageの作成の時に回転角度を設定する必要があったので74行目で0度を指定していたけど
.RenderTransform = New RotateTransformでよかった
角度指定しなくてもRotateTransformを入れるだけでよかったみたい
今気づいた
Imageの縦横回転角度とSaveDataとSliderのバインディング
Binding、DataContextの設定
この処理はアプリの起動時とセーブファイル読み込んだ直後に実行
バインディングのモードにTwoWay(双方向)を指定するようにした
これでImageのWidthやHeightを変更した時でもSaveDataのWidthやHeightも変更されるようになった
SaveDataとImageのWidthプロパティをバインディングする時
前回は
Image.SetBinding(WidthProperty, New Binding("Width"))
今回は
Dim binding as New Binding("Width")
binding.Mode = BindingMode.TwoWay
Image.SetBinding(WidthProperty, binding)
さらに回転角度のBindingの指定の方法は
BindingOperations.SetBinding(Image.RenderTransform, RotateTransform.AngleProperty, binding)
これがわからなくてググッて参照したのがこちら
【WPF】xamlと同等の内容をC#のコードで書いた例 | ザワプロ!ありがとうございます
http://zawapro.com/?p=938
47行目から49行目までの3行は書く場所間違えている、問題なく動くけど本当は
名前を付けて保存(セーブ)
画像ファイルをTiffにエンコード、SaveDataはシリアライズ、この2つを1つのZipファイルにするこの部分は
WPFとVBで複数画像(BitmapSource)とシリアライズした文字列(String)や数値(Integerとか)を1つのZipファイルにする ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログこの時とほぼ同じ、だけどムダなことしていたっぽいところを除いた
http://blogs.yahoo.co.jp/gogowaten/14079902.html
Stream関連はわかっていないからまだムダなことしてるかも
Zipの圧縮レベル指定にCompressionLevel.Fastestを指定するようにしたけど
指定しなくても同じみたい
保存したZipファイルを読み込み
画像読み込んでリストに追加するとことを少し変えただけ
For i As Integer = 0 to TiffBitmapDecoder.Frames.Count -1
bitmapList.Add(TiffBitmapDecoder.Frames(i))
Next
これを
bitmapList.AddRange(TiffBitmapDecoder.Frames)
に変えた
画像をクリックした時の処理
Button1と2を押した時の処理
Button1での処理は選択中のImageのDataContextからSaveDataを取得して
その中のプロパティに値を指定している
Button2での処理はDataListの中からSaveDataを取得して
その中のプロパティに値を指定している
どちらもできるみたいなのでどちらを使おうかなあってところ
特別なことがなければButton1の方法がラクかな
Button3クリックした時の処理
前回はこれが期待通りに動かせなかったけど解消できた
1つはさっき(19行目から)のバインディングのモードを双方に指定することで
もう1つがさっき(26行目)でBindingOperationsを使ってバインディングする方法に関連しているけど、回転角度の指定の方法を変えたこと
回転角度を60度に指定する時
前回は
Image.RenderTransform = New RotateTransform(60)
こうしていたのを今回は
Image.RenderTransform.SetValue(RotateTransform.AngleProperty, 60.0R)
こう変えた
回転角度の指定の方法が良くないんだなあと思っていて、それでもRenderTransformはあっているだろうから、その中でなんか良さそうなのがないかなあって一覧表を眺めていたら
ググッて
x:NameもしくはFindNameの怪 その1 - k_maruの思うところ2助かりました
http://kmaru.hatenablog.com/entry/20081216/1229437297
silverlight - XAML: make a ScrollViewer show scrollbars When the ScaleTransform Of a child Object gets big - Stack Overflow
http://stackoverflow.com/questions/2394370/xaml-make-a-scrollviewer-show-scrollbars-when-the-scaletransform-of-a-child-obj
前回の方法だとバインディングが外れてしまったように無効になっていたのは、RotateTransformを上書きする形になっていたのから?
今回の方法ではRotateTransformはそのままで、そのなかのAnglePropertyの値だけ変更するような形だからバインディングはそのまま保たれているってことかなあ
あとはAnglePropertyに指定する値はDouble型だからなのか普通に60って指定するとエラー
これはなんか方法があったはずだなあってググッてこちら
リテラルとサフィックス -Programming / .NET Framework/基本的なデータ型 - 総武ソフトウェア推進所ありがとうございます
'http://smdn.jp/programming/netfx/basic_types/1_literal_suffix/
60.0RってRを数値の後ろに付け加えればいいみたい
他には#を付けるか、小数点以下まで入れる
でもなんでRなんだろうねえ
そんなこんなでなんとかできた
今回のでテストが終わったので次は本番のPixtack紫陽花2ndに名前を付けて保存を付ける、時間かかりそうだなあ
Imageとかの回転角度を指定するときは最初だけ
Image.RenderTransform = New RotateTransform(30)
こんなふうにNewでRotateTransformを作ったのを指定して
それ以降は例えば60度に変更するときはSetValueを使って
Image.RenderTransform.SetValue(RotateTransform.AngleProperty, 60.0R)
こうするのがいい…のかな
コード
Wpf_test104_データバインドとシリアライズZip - Visual Studio Team Services
https://gogowaten.visualstudio.com/DefaultCollection/WPF/_git/WPF_test6?path=%2FWpf_test104_%E3%83%87%E3%83%BC%E3%82%BF%E3%83%90%E3%82%A4%E3%83%B3%E3%83%89%E3%81%A8%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BAZip&version=GBmaster&_a=contents
関連記事
WPFとVB.NET、複数のBitmapSourceを1つにしてシリアライズしてファイルに保存 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14072509.html
WPFとVB.NETでデータをシリアライズしてZipファイルに保存 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14077359.html
WPFとVBで複数画像(BitmapSource)とシリアライズした文字列(String)や数値(Integerとか)を1つのZipファイルにする ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14079902.html
WPFとVB.NETでDataContextやBinding、INotifyPropertyChangedの練習 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14088361.html