WPFのInkCanvasの描画情報はISF形式(InkSerializedFormat)で保存することに対応しており比較的簡単にできますが、さすがに頻繁にアクセスする場合や複数人で共同作業する場合などではいちいちファイルに対してFileStreamなどを利用してアクセスする必要があり使い勝手が悪くなってしまいます。
特に複数人で連携するようなケースでは、あって使い勝手が悪くなってしまします。
ですが、以下のような形で描画情報をデータベースに保存するようにすれば、ファイルロックなどの問題も簡単に、かつ便利に利用することが可能になります。
また、もちろんデータベースの機能がフルに使えますので、保守性やセキュリティ的にも何の問題もなくなります。
対応方法
まず、初めにInkCanvasからStrokeCollectionを使ってStrokesからバイト配列を取得します。
C#のコード
//描画データを取り出す byte[] stroke_data; using (MemoryStream ms = new MemoryStream()) { MyInkCanvas.Strokes.Save(ms); stroke_data = ms.ToArray(); } //データベースへ格納(※ID列はオートナンバー) SqlConnection conn = new SqlConnection(@"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = localDB.mdf;Integrated Security = True"); conn.Open(); string sql = "INSERT INTO t_stroke (stroke_data) VALUES (@stroke_data)"; SqlCommand comm = new SqlCommand(sql, conn); comm.Parameters.AddWithValue("@stroke_data", stroke_data); comm.ExecuteNonQuery(); conn.Close();
ISFファイルを開いてみた方はわかると思いますが、バイナリ形式で保存されていますので、バイト型でデータベースに保存することで、遠隔地からでも同じように簡単に、データベースから描画情報を取得することができるようになります。
C#のコード
//データベースから取り出す SqlConnection conn = new SqlConnection(@"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = localDB.mdf;Integrated Security = True"); conn.Open(); string sql = "SELECT TOP 1 stroke_data FROM t_stroke ORDER BY id DESC "; SqlCommand comm = new SqlCommand(sql, conn); byte[] stroke_data = (byte[])comm.ExecuteScalar(); conn.Close(); //描画データを反映 using (MemoryStream ms = new MemoryStream(stroke_data)) { MyInkCanvas.Strokes = new StrokeCollection(ms); ms.Close(); }
※サンプルではSQLServerのLocalDBを利用していますが、接続情報はお使いの環境に応じて適宜書き換えてください。
これで自由自在にバックアップもできますので、InkCanvasがさらに便利になります。
参考:
https://www.centrolutions.com/blog/post/2008/12/20/Save-WPF-Ink-Strokes-To-a-Database.aspx