TreeView изменить знечение по кл. F2

Автор Тема: TreeView изменить знечение по кл. F2  (Прочитано 6912 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Подскажите, есть ли какое совойство или метод у конрола TreeView
что его ноды можно было редактировать по нажатию кл. F2.
Или мне нужно все самому делать.
Обрабатывать событие KeyDown и т.п.





Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #1 : 28-03-2017, 14:45:49 »
На VB я это в Windows.Forms делал так:

Код - vb.net [Выбрать]
  1.     Private Sub LU_KeyUp(sender As Object, e As KeyEventArgs) Handles LU.KeyUp
  2.         If e.KeyCode = Keys.F2 Then
  3.             DirectCast(sender, ListView).SelectedItems(0).BeginEdit() ' вывожу в режим изменения текста элмента TreeItem
  4.         End If
  5.     End Sub

А вот в C# на WPF метода BeginEdit() пока не нашел.
Может как-то по другому?

Пока только один сопосб нашел.
Подставляю в элемент дерева TextBox

Код - C# [Выбрать]
  1. TreeViewItem.Header = new TextBox();




Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: TreeView изменить знечение по кл. F2
« Ответ #2 : 29-03-2017, 15:59:54 »
Тут многое зависит от того, как реализован TreeView. Покажите код (xaml + xaml.cs).

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #3 : 29-03-2017, 16:47:04 »
В XAML'e ни чего такого особенного нет просто на форме лежит один элемент
Код - XML [Выбрать]
  1. <Grid>
  2. <TreeView x:Name ="objTree"/>
  3. </Grid>

Ноды формирую в рантайме.
Вот фрагмент подпрограммы, в которая инициализирует редактор элемента

Код - C# [Выбрать]
  1.     selTreeItem = (TreeViewItem)this.objTree.SelectedItem;
  2.      BufContent = selTreeItem.Header; // Запоминаю то что было чтобы потом после редактирования вернуть.
  3.  
  4.             if (EditBox == null) { // Создаю редактор
  5.                 EditBox = new TextBox();
  6.                 EditBox.KeyUp += objEdit_KeyUp; // подкл. обрабочик события
  7.                 EditBox.LostFocus += TextBox_LostFocus; // подкл. обрабочик события
  8.                 EditBox.Background = Brushes.LightYellow;  
  9.                 EditBox.TextChanged += objEdit_TextChange; // подкл. обрабочик события
  10.             }
  11.                 EditBox.Text = selTreeItem.Header.ToString();
  12.                 selTreeItem.Header = EditBox;
  13.                 selTreeItem.Focus(); // передаю фокус этому редактор, но фокус не передается почему-то.
  14.                 (selTreeItem.Header as TextBox).SelectAll(); // Выделяю весь текств редактора

На картике результат выполнения.


Отмечено как Решение Алексей (IdeaSoft) 31-03-2017, 01:41:27

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: TreeView изменить знечение по кл. F2
« Ответ #4 : 29-03-2017, 18:18:02 »
Наверное, с точки зрения идеологии WPF - это не совсем правильный подход. Но работает.
Видео:

xaml:
Код - XML [Выбрать]
  1. <Window x:Class="WpfApp1.MainWindow"
  2.        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.        SizeToContent="WidthAndHeight"
  5.        WindowStartupLocation="CenterScreen">
  6.     <TreeView Name="tView" KeyUp="tView_KeyUp"/>
  7. </Window>
xaml.cs:
Код - C# [Выбрать]
  1. using System.Windows;
  2. using System.Windows.Controls;
  3. using System.Windows.Input;
  4.  
  5. namespace WpfApp1
  6. {
  7.     /// <summary>
  8.     /// Interaction logic for MainWindow.xaml
  9.     /// </summary>
  10.     public partial class MainWindow : Window
  11.     {
  12.         public MainWindow()
  13.         {
  14.             InitializeComponent();
  15.             var node1 = AddItem(tView, "Text1");
  16.             var node11 = AddItem(node1, "Text11");
  17.             AddItem(node11, "Text111");
  18.             AddItem(node11, "Text112");
  19.             AddItem(tView, "Text2");
  20.             AddItem(tView, "Text3");
  21.         }
  22.  
  23.         TreeViewItem AddItem(ItemsControl itemsControl, string text)
  24.         {
  25.             Grid gr = new Grid();
  26.             TextBlock tBlk = new TextBlock() { Text = text };
  27.             TextBox tBox = new TextBox() { Visibility = Visibility.Collapsed };
  28.             gr.Children.Add(tBlk);
  29.             gr.Children.Add(tBox);
  30.             gr.LostKeyboardFocus += gr_LostKeyboardFocus;
  31.             TreeViewItem item = new TreeViewItem();          
  32.             item.Header = gr;
  33.             itemsControl.Items.Add(item);          
  34.             return item;
  35.         }
  36.  
  37.         private void tView_KeyUp(object sender, KeyEventArgs e)
  38.         {
  39.             if (e.Key != Key.F2) return;
  40.             TreeViewItem selTreeItem = tView.SelectedItem as TreeViewItem;
  41.             if (selTreeItem == null) return;
  42.             Grid gr = selTreeItem.Header as Grid;            
  43.             TextBlock tBlock = gr.Children[0] as TextBlock;
  44.             TextBox tBox = gr.Children[1] as TextBox;
  45.             tBox.Text = tBlock.Text;
  46.             tBlock.Visibility = Visibility.Collapsed;
  47.             tBox.Visibility = Visibility.Visible;
  48.             tBox.Focus();
  49.             tBox.SelectAll();
  50.         }
  51.  
  52.         private void gr_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
  53.         {
  54.             Grid gr = sender as Grid;
  55.             TextBlock tBlock = gr.Children[0] as TextBlock;
  56.             TextBox tBox = gr.Children[1] as TextBox;
  57.             tBlock.Text = tBox.Text;
  58.             tBox.Visibility = Visibility.Collapsed;
  59.             tBlock.Visibility = Visibility.Visible;          
  60.         }
  61.     }
  62. }
  63.  

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #5 : 29-03-2017, 19:02:33 »
Наверное, с точки зрения идеологии WPF - это не совсем правильный подход
А что тут неправильного?
В вашем примере элемент TreeViewItem содержит Grid+ textBox и TextBlock
и вы просто чередуете видиость элементов.
Разница только в том, что я использовал всего 1 элемент TextBox, а вашем
примере каждый TreeViewItem изначально содержит Grid с двумя элементами.
В принципе только оперативная память больше расходуется, т.к. TextBox
заранее есть для каждого элемента.

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #6 : 29-03-2017, 19:10:35 »
С элементом Grid даже универсальнее получится.
А вдруг мне захочится добавить в элемент
еще CheckBox или что то еще.

Мне WPF тем нравится, что можно
придумывать составные элементы под разные задачки
и замысловатые интерфейсы.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: TreeView изменить знечение по кл. F2
« Ответ #7 : 29-03-2017, 19:27:16 »
Разница только в том, что я использовал всего 1 элемент TextBox, а вашем
примере каждый TreeViewItem изначально содержит Grid с двумя элементами.
В принципе только оперативная память больше расходуется, т.к. TextBox
заранее есть для каждого элемента.
Почему-то в Вашем варианте, когда TextBox создается "на лету", не работает фокусировка на TextBox. Поэтому и выбрал вариант создания его при наполнении TreeView. Возможно, если поразбираться в причинах, можно как-то справиться и с Вашим вариантом.
С элементом Grid даже универсальнее получится.
А вдруг мне захочится добавить в элемент
еще CheckBox или что то еще.
Даже, наверное, лучше использовать StackPanel, чтобы не было дополнительных телодвижений со строками и столбцами.
Мне WPF тем нравится, что можно
придумывать составные элементы под разные задачки
и замысловатые интерфейсы.
Дык :)

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #8 : 29-03-2017, 21:10:01 »
Я тоже вот не могу понять почему в моем примере 
фокус не почает TextBox.

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #9 : 31-03-2017, 01:45:21 »
Спасибо за ответы я разобрался с фокусом.
За основу взял ваш пример, только сделал чуть по другому.
Создаю TextBox,  в TreeViewItem, не сразу, а
только когда это необходимо пользователю.

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: TreeView изменить знечение по кл. F2
« Ответ #10 : 31-03-2017, 02:06:04 »
Вот такая реализация.

Код - C# [Выбрать]
  1.     public class TreeItem : Grid {
  2.  
  3.         private TreeViewItem Root; // "Корень" редактируемого элемента (для проверки на совпадение)
  4.         private TextBlock ElemText; // Элемент текста
  5.         private TextBox ElemEdit;    // Редактор
  6.         private bool PresKeyEnterOrEsc; // Этот флаг нужен, чтобы не вызывать метод EndEdit второй раз
  7.        
  8.         ////Конструктор //////////////////////////////////////////////////////////////////////////////////
  9.         public TreeItem(string text) {
  10.             ElemText = new TextBlock() { Text = text };
  11.             Children.Add(ElemText);
  12.             this.LostKeyboardFocus += grid_LostKeyboardFocus;
  13.         }
  14.         //// Возвращает текст элемента ///////////////////////////////////////////////////////////////////
  15.         public string GetText() {
  16.             if (ElemText != null)
  17.                 return ElemText.Text;
  18.             else
  19.                 return "";
  20.         }
  21.         //////проверка, является ли элементов в режиме редактирования /////////////////////////////////////
  22.         public bool isEditing() {
  23.             if (this.ElemEdit != null)
  24.                 return ElemEdit.Visibility  == Visibility.Visible;
  25.             else
  26.                 return false;
  27.         }
  28.         ///// Возвращает текст в момент редактирования элемента /////////////////////////////////////////
  29.         public string GetEditText() {
  30.             if (this.ElemEdit != null)
  31.                 return ElemEdit.Text;
  32.             else
  33.                 return "";
  34.         }
  35.         //////Запуск режима редактора ///////////////////////////////////////////////////////////////////
  36.         public void BeginEdit(TreeViewItem _Root) {
  37.             PresKeyEnterOrEsc = false;
  38.             this.ElemText.Visibility = Visibility.Collapsed;
  39.             if (ElemEdit == null) {
  40.                 ElemEdit = new TextBox();  
  41.                 ElemEdit.KeyUp += TextBox_KeyUp;
  42.                 ElemEdit.Background = Brushes.LightYellow;  
  43.                 ElemEdit.LostFocus += TextBox_LostFocus;
  44.                 Children.Add(ElemEdit);
  45.             }
  46.             // корневой элемент для проверки на совпадающие имена элементов
  47.             Root = _Root;  
  48.             ElemEdit.Visibility = Visibility.Visible;
  49.             ElemEdit.Text = ElemText.Text;
  50.             ElemEdit.Focus();
  51.             ElemEdit.SelectAll();
  52.         }
  53.         ///// "Откат" изменения, если пользователь передумал, нажав кл. "ESC"
  54.         //// или если есть такой элемент среди дочерних для одного корневого элемента
  55.         public void RollBack() {
  56.             this.ElemText.Visibility = Visibility.Visible;
  57.             if (ElemEdit != null)
  58.                 ElemEdit.Visibility = Visibility.Collapsed;
  59.         }
  60.         ///// Подтверждение изменения текста элемента ////////////////////////////////////////////////////
  61.         public void Commit() {
  62.             ElemText.Visibility = Visibility.Visible;
  63.             if (ElemEdit != null) {
  64.                 ElemEdit.Visibility = Visibility.Collapsed;
  65.                 ElemText.Text = ElemEdit.Text;    
  66.             }
  67.         }
  68.         ////// Завершение работы режима редактирования //////////////////////////////////////////////////
  69.         private void EndEdit() {
  70.             if (PresKeyEnterOrEsc) return;
  71.             if (isEditing()) {
  72.                 bool CanEdit = true;
  73.                 if (Root != null) { // проверка на совпадение текстов среди дочерних элементов
  74.                     foreach (TreeViewItem itm in Root.Items)
  75.                         if ((itm.Header as TreeItem).GetText().Trim() == ElemEdit.Text.Trim()) {
  76.                             CanEdit = false;
  77.                             break;
  78.                         }
  79.                 }
  80.                 if (CanEdit) Commit();
  81.                 else RollBack();
  82.             }
  83.         }
  84.         ////// обработка события клавиатуры /////////////////////////////////////////////////////////////
  85.         private void TextBox_KeyUp(object sender, KeyEventArgs e) {
  86.             if (e.Key == Key.Enter) {// Принимаем ввод нового значения клавише "Enter"
  87.                 EndEdit();
  88.                 PresKeyEnterOrEsc = true;
  89.             }
  90.             if (e.Key == Key.Escape) { // Делаем "откат" по клавише "Esc"
  91.                 RollBack();
  92.                 PresKeyEnterOrEsc = true;
  93.             }
  94.         }
  95.         //////// обработчик события потери фокуса редактора текста //////////////////////////////////////
  96.         private void TextBox_LostFocus(object sender, RoutedEventArgs e)  {
  97.             EndEdit();
  98.         }
  99.         ////////// обработчик события потери фокуса grid //////////////////////////////////////////////////
  100.         private void grid_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
  101.             EndEdit();
  102.         }
  103.     }


И объект этого класса присваевается элементу дерева
Код - C# [Выбрать]
  1.             TreeViewItem itm = new TreeViewItem();
  2.             itm.Header = new TreeItem(s);

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: TreeView изменить знечение по кл. F2
« Ответ #11 : 31-03-2017, 11:56:53 »
А что тут неправильного?
Все же, думаю, что используя такие возможности WPF, как шаблоны и привязка данных, свойства зависимостей и т.п., эту задачу можно было бы решить гораздо изящнее. Но у меня пока нет времени и желания заниматься этим. В принципе, раз все хорошо работает, то почему бы и не оставить так? ;)