Вопрос

У меня есть вложенный TreeView где я привязываю событие doubleclick к каждому элементу, чтобы текст узла был изменен на редактируемое текстовое поле.Затем я использую обработчик событий LostFocus, чтобы удалить текстовое поле и восстановить текст.

  void treeViewItemWithMenu_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        if (selected == e.Source)
        {
            TextBox tb = new TextBox();
            tb.Text = this.Header.ToString();
            tb.Focus();
            tb.LostFocus += new RoutedEventHandler(tb_LostFocus);
            this.Header = tb;
            var a = e.OriginalSource;
            e.Handled = true;
        }
    }


    void tb_LostFocus(object sender, RoutedEventArgs e)
    {
        this.Header = ((TextBox)(this.Header)).Text;
    }

К сожалению, не похоже, что событие LostFocus работает корректно.Когда я щелкаю за пределами текстового поля, оно вообще не срабатывает.Я могу даже дважды щелкнуть на другом узле, и он переходит в режим редактирования (т. Е. становится текстовым полем), в то время как первое текстовое поле, похоже, все еще находится в фокусе.Потерянный фокус не срабатывает до тех пор, пока я не начну переходить туда-сюда между двумя текстовыми полями.

Я использую vs2010 rc с проектом, установленным на .net 3.5.

Это было полезно?

Решение

О боже!Простите, что я так говорю, но каждый обычный пользователь WPF, прочитавший ваш вопрос, вероятно, сочувственно покачал головой.Нам жаль вас, потому что вы еще не познали истинный "Дзен WPF", который заключается в использовании привязки данных, шаблонов и триггеров для придания вашему пользовательскому интерфейсу динамичности, а не в том, чтобы делать это старомодным способом.WPF прекрасен из-за этой способности.Это также упрощает задачу на "1000%".

Я рекомендую вам изменить свой пользовательский интерфейс, чтобы использовать триггер в вашем TreeViewItem для замены вашего HeaderTemplate на основе свойства, которое вы определяете в TreeViewItem.Установите для этого свойства значение true при двойном щелчке по элементу.Установите значение false, когда IsKeyboardFocusWithin становится false (вы можете переопределить метаданные и добавить для этого PropertyChangedCallback).

Что касается вашей проблемы с потерянным фокусом, я подозреваю, что ваша проблема в том, что у вас несколько областей фокусировки или это ошибка в RC.Не видя вашего XAML, я не могу сказать намного больше, чем это.

Дополнительные сведения о том, как сделать это "способом WPF"

Вот некоторые подробности о том, как это реализовать, используя прикрепленное свойство, триггеры и шаблоны.

Ваши шаблоны могут быть настолько простыми или сложными, насколько вы захотите.Вот просто:

<DataTemplate x:Key="NormalTemplate">
  <ContentPresenter />
</DataTemplate>

<DataTemplate x:Key="TextBoxTemplate">
  <TextBox Text="{Binding}" />
</DataTemplate>

Вот как выглядел бы ваш стиль:

<Style TargetType="TreeViewItem">
  <Setter Property="HeaderTemplate" Value="{StaticResource NormalTemplate}" />
  <Trigger Property="local:MyWindowClass.ShowTextBox" Value="true">
    <Setter Property="HeaderTemplate" Value="{StaticResource TextBoxTemplate}" />
  </Trigger>
</Style>

Прикрепленное свойство "ShowTextBox" можно создать в MyWindowClass, используя фрагмент "propa" - просто введите "propa" и нажмите tab, затем заполните пробелы.

Чтобы переключить элемент на отображение текстового поля, просто:

SetShowTextBox(item, true);

Чтобы переключить его обратно:

SetShowTextBox(item, false);

Я надеюсь, что это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top