WPF Lostfocus не стреляет корректно - PullRequest
2 голосов
/ 16 февраля 2010

У меня есть вложенное TreeView, где я связываю событие двойного щелчка для каждого элемента, чтобы текст узла был изменен на редактируемое текстовое поле. Затем я использую обработчик событий 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.

1 Ответ

2 голосов
/ 17 февраля 2010

Боже мой! Прошу прощения за мои слова, но каждый обычный пользователь WPF, прочитавший ваш вопрос, вероятно, пожалел головой. Нам грустно за вас, потому что вы еще не изучили настоящий «Zen of WPF», который использует привязку данных, шаблоны и триггеры, чтобы сделать ваш интерфейс динамичным, а не делать это старомодным способом. WPF прекрасен благодаря этой способности. Это также облегчает работу на 1000%.

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

Что касается вашей проблемы с LostFocus, я подозреваю, что ваша проблема в том, что у вас есть несколько областей фокусировки или это ошибка в 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» и нажмите вкладку, затем заполните пробелы.

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

SetShowTextBox(item, true);

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

SetShowTextBox(item, false);

Надеюсь, это поможет.

...