У меня есть обработчик события для события 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);
}