我在我的表单上有一个TextBox.TextChanged事件的事件处理程序.为了支持撤销,我想弄清楚TextBox中究竟发生了哪些变化,以便我可以在用户要求时撤消更改.(我知道内置文本框支持撤消,但我希望整个应用程序只有一个撤消堆栈)
有合理的方法吗?如果没有,是否有更好的方法来支持这样的撤消功能?
编辑:像下面的东西似乎工作 - 有什么更好的想法?(在这种情况下,我真的希望.NET有类似STL std::mismatch算法的东西......
class TextModification
{
private string _OldValue;
public string OldValue
{
get
{
return _OldValue;
}
}
private string _NewValue;
public string NewValue
{
get
{
return _NewValue;
}
}
private int _Position;
public int Position
{
get
{
return _Position;
}
}
public TextModification(string oldValue, string newValue, int position)
{
_OldValue = oldValue;
_NewValue = newValue;
_Position = position;
}
public void RevertTextbox(System.Windows.Forms.TextBox tb)
{
tb.Text = tb.Text.Substring(0, Position) + OldValue + tb.Text.Substring(Position + NewValue.Length);
}
}
private Stack<TextModification> changes = new Stack<TextModification>();
private string OldTBText = "";
private bool undoing = false;
private void Undoit()
{
if (changes.Count == 0)
return;
undoing = true;
changes.Pop().RevertTextbox(tbFilter);
OldTBText = tbFilter.Text;
undoing = false;
}
private void UpdateUndoStatus(TextBox caller)
{
int changeStartLocation = 0;
int changeEndTBLocation = caller.Text.Length;
int changeEndOldLocation = OldTBText.Length;
while (changeStartLocation < Math.Min(changeEndOldLocation, changeEndTBLocation) &&
caller.Text[changeStartLocation] == OldTBText[changeStartLocation])
changeStartLocation++;
while (changeEndTBLocation > 1 && changeEndOldLocation > 1 &&
caller.Text[changeEndTBLocation-1] == OldTBText[changeEndOldLocation-1])
{
changeEndTBLocation--;
changeEndOldLocation--;
}
changes.Push(new TextModification(
OldTBText.Substring(changeStartLocation, changeEndOldLocation - changeStartLocation),
caller.Text.Substring(changeStartLocation, changeEndTBLocation - changeStartLocation),
changeStartLocation));
OldTBText = caller.Text;
}
private void tbFilter_TextChanged(object sender, EventArgs e)
{
if (!undoing)
UpdateUndoStatus((TextBox)sender);
}
Run Code Online (Sandbox Code Playgroud)