public class TreeItem : Grid {
private TreeViewItem Root; // "Корень" редактируемого элемента (для проверки на совпадение)
private TextBlock ElemText; // Элемент текста
private TextBox ElemEdit; // Редактор
private bool PresKeyEnterOrEsc; // Этот флаг нужен, чтобы не вызывать метод EndEdit второй раз
////Конструктор //////////////////////////////////////////////////////////////////////////////////
public TreeItem(string text) {
ElemText = new TextBlock() { Text = text };
Children.Add(ElemText);
this.LostKeyboardFocus += grid_LostKeyboardFocus;
}
//// Возвращает текст элемента ///////////////////////////////////////////////////////////////////
public string GetText() {
if (ElemText != null)
return ElemText.Text;
else
return "";
}
//////проверка, является ли элементов в режиме редактирования /////////////////////////////////////
public bool isEditing() {
if (this.ElemEdit != null)
return ElemEdit.Visibility == Visibility.Visible;
else
return false;
}
///// Возвращает текст в момент редактирования элемента /////////////////////////////////////////
public string GetEditText() {
if (this.ElemEdit != null)
return ElemEdit.Text;
else
return "";
}
//////Запуск режима редактора ///////////////////////////////////////////////////////////////////
public void BeginEdit(TreeViewItem _Root) {
PresKeyEnterOrEsc = false;
this.ElemText.Visibility = Visibility.Collapsed;
if (ElemEdit == null) {
ElemEdit = new TextBox();
ElemEdit.KeyUp += TextBox_KeyUp;
ElemEdit.Background = Brushes.LightYellow;
ElemEdit.LostFocus += TextBox_LostFocus;
Children.Add(ElemEdit);
}
// корневой элемент для проверки на совпадающие имена элементов
Root = _Root;
ElemEdit.Visibility = Visibility.Visible;
ElemEdit.Text = ElemText.Text;
ElemEdit.Focus();
ElemEdit.SelectAll();
}
///// "Откат" изменения, если пользователь передумал, нажав кл. "ESC"
//// или если есть такой элемент среди дочерних для одного корневого элемента
public void RollBack() {
this.ElemText.Visibility = Visibility.Visible;
if (ElemEdit != null)
ElemEdit.Visibility = Visibility.Collapsed;
}
///// Подтверждение изменения текста элемента ////////////////////////////////////////////////////
public void Commit() {
ElemText.Visibility = Visibility.Visible;
if (ElemEdit != null) {
ElemEdit.Visibility = Visibility.Collapsed;
ElemText.Text = ElemEdit.Text;
}
}
////// Завершение работы режима редактирования //////////////////////////////////////////////////
private void EndEdit() {
if (PresKeyEnterOrEsc) return;
if (isEditing()) {
bool CanEdit = true;
if (Root != null) { // проверка на совпадение текстов среди дочерних элементов
foreach (TreeViewItem itm in Root.Items)
if ((itm.Header as TreeItem).GetText().Trim() == ElemEdit.Text.Trim()) {
CanEdit = false;
break;
}
}
if (CanEdit) Commit();
else RollBack();
}
}
////// обработка события клавиатуры /////////////////////////////////////////////////////////////
private void TextBox_KeyUp(object sender, KeyEventArgs e) {
if (e.Key == Key.Enter) {// Принимаем ввод нового значения клавише "Enter"
EndEdit();
PresKeyEnterOrEsc = true;
}
if (e.Key == Key.Escape) { // Делаем "откат" по клавише "Esc"
RollBack();
PresKeyEnterOrEsc = true;
}
}
//////// обработчик события потери фокуса редактора текста //////////////////////////////////////
private void TextBox_LostFocus(object sender, RoutedEventArgs e) {
EndEdit();
}
////////// обработчик события потери фокуса grid //////////////////////////////////////////////////
private void grid_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
EndEdit();
}
}