Пусть TreeView обновит свой SelectedItem при программном изменении - PullRequest
2 голосов
/ 23 ноября 2011

В WPF у меня есть элемент управления TreeView, где конкретный элемент может быть выбран либо пользователем, выбирающим элемент непосредственно в виде дерева, либо нажатием на элемент управления экрана.В древовидном представлении отображается список элементов, отображаемых в пользовательской форме, в основном это приложение-дизайнер форм.

Вот моя проблема.Когда пользователь нажимает на элемент управления экрана, он вызывает метод, который возвращает TreeViewItem, который представляет элемент.Затем он устанавливает для свойства IsSelected значение true для этого элемента.Он корректно изменяет визуальный индикатор в TreeView и вызывает событие SelectedItemChanged в TreeView.Это все хорошо.

Однако, кажется, что где-то за кадром TreeView все еще думает, что предыдущий элемент выбран.Вот почему я пришел к такому выводу.Если я выберу ElementA, щелкнув по нему в TreeView, он будет правильно выбран.Если я затем выберу ElementB, нажав на элемент управления экрана и программно установив свойство IsSelected для ElementB TreeViewItem, то, похоже, оно выбрало его правильно.Теперь, если я снова выберу ElementA, щелкнув по нему в TreeView, он ничего не сделает.Событие SelectedItemChanged не вызывается, и обратное поле выбора, указывающее выбранный элемент, остается в ElementB.Если я нажимаю на ElementB в TreeView, он также не вызывает событие SelectedItemChanged, однако он не обновляет внутренний флаг, поскольку, если я затем нажимаю на ElementA в TreeView, он обрабатывает его правильно и вызывает событие.

Единственный обходной путь, который я нашел для этого, - обработчик события SelectedItemChanged для вызова метода Focus для теперь выбранного TreeViewItem.Если я делаю это, я получаю ожидаемое поведение, когда выбираю элементы управления экраном и программно изменяю выбранный TreeViewItem.

Это неприемлемое решение, поскольку оно создает мерцание при изменении фокуса.Когда я выбираю элементы в окне формы, фокус переходит к элементу управления TreeView, а затем возвращается к форме, вызывая мерцание и небольшую задержку.

У всех есть какие-либо значения.

Обновление

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

    public bool SelectItemByName(String controlName)
    {
        bool fReturn = false;
        TreeViewItem tviToSelect = FindItemByName(_tviMaster, controlName);
        if (tviToSelect != null && _tviSelectedItem != tviToSelect)
        {
            tviToSelect.IsSelected = true;

            // Make sure the selected item is visible in the TreeView by expanding all of the parent nodes
            ExpandAllParents(tviToSelect);

            tviToSelect.BringIntoView();

            fReturn = true;
        }
        return fReturn;
    }

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

Затем в моем обработчике событий SelectedItemChanged мне пришлось добавить следующую строку.

                _tviSelectedItem.Focus();

Это исправляет мою первоначальную проблему, но вводит нежелательное мерцание экрана.

Напомним, я выбираю ElementA непосредственно в TreeView, затем выбираю один или несколько других элементов в конструкторе форм, который, в свою очередь, вызывает SelectItemByName для программной установки выбранного элемента.Все визуальные индикаторы показывают, что это сработало.В TreeView выделенный элемент изменяется на новый выбранный элемент.После выбора любого количества элементов через интерфейс дизайнера формы, если вы выбираете ElementA, щелкая по нему непосредственно в TreeView, он ничего не делает.Он не выделяется и не вызывает событие SelectedItemChanged.Если вы проверите свойства SelectedItem и SelectedValue TreeView, все они правильно соответствуют элементу, который был выбран программным образом.Однако элемент управления где-то, кажется, думает, что ElementA все еще выбран и не распознает, что выбор меняется.

Я не могу поверить, что другие люди не сталкивались с этим.Похоже, это существенный недостаток управления TreeView в WPF.Не уверен, что у WinForms такая же проблема или нет.

1 Ответ

0 голосов
/ 23 ноября 2011

Каждый TreeViewItem имеет свойство IsSelected, и я подозреваю, что старое не имеет значения false.Попробуйте установить его в значение «ложь» всякий раз, когда вы устанавливаете для нового элемента значение «истина».

var currentItem = treeView.ItemContainerGenerator
    .ContainerFromItem(treeView.SelectedItem) as TreeViewItem;
currentItem.IsSelected = false;

Если это не сработает, попробуйте установить фокус на вновь выбранный элемент одновременно с его выбором.Не забывайте, что в WPF также есть две области фокусировки: логическая фокусировка и фокусировка клавиатуры.Возможно, вам придется установить оба.

treeViewItem.Focus();         // Sets Logical Focus
Keyboard.Focus(treeViewItem); // Sets Keyboard Focus
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...