2012-10-20 9 views
5

TextBox에 대해 매우 간단한 실행 취소 기능을 사용하고 있으며 이상한 문제가 있습니다. 모든 변경 내용이 들어있는 Stack에서 문자열을 가져 와서 텍스트 상자 안에 넣으려고하면 변경 사항이 표시되지 않습니다.텍스트 상자의 기능을 취소하십시오.

약간의 디버그 라벨을 작성하여 실제로 작동하는지 확인합니다. 레이블에서 작동한다는 것을 알았지 만 텍스트 상자에서는 자체 Undo 기능을 사용합니다.

취소하거나 텍스트 상자를 취소하고 내 자신의 기능을 사용하는 방법이 있습니까?

private void Form1_KeyDown(object sender, KeyEventArgs e) 
     if (e.KeyCode == Keys.Z && (ModifierKeys & Keys.Control) == Keys.Control) 
      { 
       nameTextBox.Text = undoName.GetLastChange(); //--> not working 

       undoDebuglabel.Text = undoName.GetLastChange(); --> working 
      } 
} 

GetLastChange()는 클래스 내부의 Stack에서 정보를 얻고있다 :

여기에 내가 만든 변경의 샘플 코드입니다.

텍스트 상자에서 변경 사항을 볼 수없는 것과 같습니다. 동일한 단축키 인 CTRL + Z을 사용하고 있기 때문에 그럴 수 있습니까?

+0

내가 게시 한 코드는 정상적으로 작동합니다. –

+0

텍스트 상자 안의 스택에서 변경 사항을 확인 하시겠습니까? – samy

+0

예. 분명히 당신이 그것을 채우기 위해하는 정확한 코드를 가지고 있지는 않지만 개념은 같습니다. –

답변

4

ClearUndo 메서드를 사용하여 텍스트 상자 자체 스택을 지우십시오. 시도해보십시오.

+0

아, 네, 미안 해요. – keyboardP

+0

WinForm 대안으로 업데이트되었습니다. – keyboardP

+0

예 작업 thx! – samy

3

고유 한 TextBox를 만들어 System.Windows.Forms.TextBox에서 상속함으로써 기록을 처리 할 수 ​​있습니다.

public class HistoryTextBox: System.Windows.Forms.TextBox 
{ 
    bool ignoreChange = false; 
    List<string> storage = null; 


    protected override void OnCreateControl() 
    { 
     base.OnCreateControl(); 
     //init storage... 
     storage = new List<string>(); 
    } 

    protected override void OnTextChanged(EventArgs e) 
    { 
     base.OnTextChanged(e); 
     //save change to storage... 
     if (!ignoreChange) 
     { 
      storage.Add(this.Text); 
     } 
    } 

    public void Undo() 
    { 
     if (storage.Count > 0) 
     { 
      this.ignoreChange = true; 
      this.Text = storage[storage.Count - 1]; 
      storage.RemoveAt(storage.Count - 1); 
      this.ignoreChange = false; 
     } 
    } 
} 

매번 당신은 전화를 취소해야 : 내 샘플을 살펴 보자

historyTextBox1.Undo(); 

이 클래스는 당신에게 여러 histoy 기록을 제공 할 것입니다.

+0

정의에서 ignoreChange를 false로 설정하고 저장소 변수 뒤에 OnCreateControl에서 true로 설정해야했습니다. OnTextChanged 저장소 변수에 대한 시작시 null이 발생했습니다. 내 TextBox가 기본 텍스트로 시작하고 OnTextChanged를 일찍 트리거했기 때문에 이것이라고 생각합니다. –

0

나는 확대하여 Geregor 님과 키보드 님의 답변입니다. Visual Studio 2017에 게시 된 코드가 작동하지 않아 사소한 수정이있었습니다. 그런 다음 다시 실행 기능을 원했기 때문에 몇 줄의 코드를 추가했습니다. 이것은 내 테스트에서 잘 작동하는 것 같아서 질문에 답하고 확장하기 때문에 공유 할 것이라고 생각했습니다.

이 코드는 실행 취소, 다시 실행을 추가하고 Ctrl-Z 또는 Ctrl-Y를 길게 눌러 목록에서 "실행"하도록 할 수 있습니다.

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 

namespace CodeBuilder 
{ 
    public class HistoryTextBox : System.Windows.Forms.TextBox 
    { 
     bool ignoreChange = true; 
     List<string> storageUndo = null; 
     List<string> storageRedo = null; 


     protected override void OnCreateControl() 
     { 
      base.OnCreateControl(); 
      storageUndo = new List<string>(); 
      storageRedo = new List<string>(); 
      ignoreChange = false; 
     } 

     protected override void OnTextChanged(EventArgs e) 
     { 
      base.OnTextChanged(e); 
      if (!ignoreChange) 
      { 
       this.ClearUndo(); 
       if (storageUndo.Count > 2048) storageUndo.RemoveAt(0); 
       if (storageRedo.Count > 2048) storageRedo.RemoveAt(0); 

       storageUndo.Add(this.Text); 
      } 
     } 

     protected override void OnKeyDown(KeyEventArgs e) 
     { 

      if (e.KeyCode == Keys.Z && (ModifierKeys & Keys.Control) == Keys.Control) 
      { 
       this.ClearUndo(); 
       ignoreChange = true; 
       this.Undo(); 
       ignoreChange = false; 
      } 
      else if (e.KeyCode == Keys.Y && (ModifierKeys & Keys.Control) == Keys.Control) 
      { 
       this.ClearUndo(); 
       ignoreChange = true; 
       this.Redo(); 
       ignoreChange = false; 
      } 
      else 
      { 
       base.OnKeyDown(e); 
      } 
     } 

     public void Redo() 
     { 
      if (storageRedo.Count > 0) 
      { 
       this.ignoreChange = true; 
       this.Text = storageRedo[storageRedo.Count - 1]; 
       storageUndo.Add(this.Text); 
       storageRedo.RemoveAt(storageRedo.Count - 1); 
       this.ignoreChange = false; 
      } 
     } 

     public new void Undo() 
     { 
      if (storageUndo.Count > 0) 
      { 
       this.ignoreChange = true; 
       storageRedo.Add(this.Text); 
       this.Text = storageUndo[storageUndo.Count - 1]; 
       storageUndo.RemoveAt(storageUndo.Count - 1); 
       this.ignoreChange = false; 
      } 
     } 
    } 
} 
관련 문제