C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: flexGridにおける、Undo/Redo


(過去ログ 25 を表示中)

[トピック内 2 記事 (1 - 2 表示)]  << 0 >>

■10840 / inTopicNo.1)  flexGridにおける、Undo/Redo
  
□投稿者/ りん (1回)-(2007/11/27(Tue) 23:23:45)

分類:[VB.NET/VB2005] 

VB初心者です。

標記の件について、
分からないのであまり具体的には書けませんが、
列の削除・追加・Cellの値変更に関してUndo/Redoの機能を設置したいと考えてます。
その際、データの持ち方はどのようにすれば一番良いでしょうか?
javaのようにUndo/RedoのクラスやAPIがあったりはしないのでしょうか?

何もわからないので、方向性といいますか、指針があればどなたかご教授下さい。
(こう作っていけばよいのでは?でも良いので・・)
引用返信 編集キー/
■11300 / inTopicNo.2)  Re[1]: flexGridにおける、Undo/Redo
□投稿者/ ID非公開 (5回)-(2007/12/11(Tue) 22:25:23)
5回目の投稿です。


はじめまして、ID非公開と申します。

 私はflexGridやJavaAPIのことはわかりませんが、
TextBoxで無制限Undo/Redo機能を以前作成してみたことがあります。
その経験の範囲内でお答え致します。


  用意するものは以下の2つです

1.入力操作を記録するためのクラス。

  Public Class ActionRecord
    '
    ' 以下の3つの情報があれば入力操作を完全に保存可能
    '
    Public Index As Integer  ' カーソル位置 を保存
    Public Deleted As String  ' 削除された文字列 を保存
    Public Inserted As String  ' 入力された文字列 を保存
    Public Sub New(ByVal index As Integer, ByVal deleted As String, ByVal inserted As String)
      Me.Index = index
      Me.Inserted = inserted
      Me.Deleted = deleted
    End Sub
  End Class


   ※ここで、1回の入力操作を1つのActionRecordインスタンスに対応させます。
   例えば「ab」と続けて入力した場合には、
    「a」の入力に対応するActionRecordインスタンス
    「b」の入力に対応する     同上
   をそれぞれ生成します。
    全ての入力操作について逐一ActionRecordインスタンスを生成して保存しておけば、
   完全なUndo/Redo機能を実現できます。


2.Undo操作とRedo操作の履歴を格納するためのList。

  Private UndoList As New List(Of ActionRecord)
  Private RedoList As New List(Of ActionRecord)

   ※ここに、生成したActionRecordインスタンス達を順次格納します。
   後述しますが、「リストの先頭に格納すること」がポイントです。


 <詳細の説明>

1.入力操作が行われるたびに、それに対応するActionRecordインスタンスを生成します。

  例えば「a」と入力した場合、
    反転表示されたTextがあれば削除して、
    カーソル位置に「a」を挿入。
  という処理が行われます。
  これに対応するActionRecordインスタンスは

    Dim ar As New ActionRecord(Me.SelectionStart, Me.SelectedText, "a")
     ※ 念のための補足:ここでの「Me」はTextBoxのことです。

  となります。反転表示の有無にかかわらずこの方法で対応することができます。


2.次に、これをUndoListの先頭に格納します。

    UndoList.Insert(0, ar)

  ※ここで「先頭に格納すること」がポイントです。
  なぜなら、Undo操作を行う場合に「先頭から取り出して、先頭を削除」を繰り返していけば、
  操作履歴を新しいものから順番に取り出せるからです。


3.Undo操作の流れ

  以下の処理を繰り返せばOKです。

Private LockObj As String="" ' ←この変数はどこか別の場所で宣言
  SyncLock LockObj

    Dim ar2 As ActionRecord = UndoList(0)
    '
    ' ar2の情報を元にTextBoxのTextを復元する処理をここに書く
    '
    UndoList.RemoveAt(0)
    RedoList.Insert(0, ar2) ' 今度はRedoListに格納(ここでも「先頭に格納」)

  End SyncLock

  ※Redo操作の場合も、向きが逆になるだけで、考え方は全く同じです。

  SyncLockブロックがないと、「Undoを連続実行」した際にテキストが正しく復元できません。
  (詳しい理由は私にもわかりませんが、こうしないとうまくいかないようです)


4.補足

  キーボード入力が行われる毎に、RedoListをクリアしてください。
  そうしないとRedo機能が正しく動作しません。



 TextBoxの場合は、以上の方法で無制限Undo/Redoを実現できます。
 flexGridの場合はもっと複雑になると思いますが、
 同様の考え方で対応していけば良いのではないかと思います。


  参考文献

  日経BPソフトプレス発行「プログラミングVisualBasic2005言語編(下)」、pp. 416 - 421 .

  http://hp.vector.co.jp/authors/VA007799/viviProg/doc3.htm


以上です。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -