TreeViewItem.ItemContainerGenerator.ContainerFromItem противоречивые результаты - PullRequest
2 голосов
/ 29 июля 2010

У меня есть TreeView на моей странице.Он связан с набором клиентов, содержащих контракты, например:

public class Client
{
  public int ClientID { get; set; }
  public string Name { get; set; }
  public List<Contract> Contracts { get; set; }
}

public class Contract
{
  public int ContractID { get; set; }
  public int ClientID { get; set; }
  public string Name { get; set; }
}

XAML для моего TreeView выглядит следующим образом:

<sdk:TreeView x:Name="tvClientContract" ItemsSource="{Binding ClientContracts}">
  <sdk:TreeView.ItemTemplate>
    <sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Contracts}">
      <TextBlock Text="{Binding Path=Name}" />
    </sdk:HierarchicalDataTemplate>
  </sdk:TreeView.ItemTemplate>
</sdk:TreeView>

Где ClientContracts - List<Clients>.Привязка работает нормально, и у меня есть иерархическая сетка.

Проблема, с которой я сталкиваюсь, заключается в том, что при открытии формы с TreeView на ней я хочу выбрать текущий клиент, в настоящее время я использую следующий код:

TreeViewItem client = (TreeViewItem)tvClientContract.ItemContainerGenerator.ContainerFromItem(aClient);

или

TreeViewItem client = (TreeViewItem)tvClientContract.ItemContainerGenerator.ContainerFromIndex(tvClientContract.Items.IndexOf(aClient));
client.IsSelected = true;

, но это возвращает противоречивые результаты, например, я открываю форму, когда выбран клиент 'ABC' и клиент будет нулевым.Я открываю его снова, когда клиент «ABC» выбран, и он возвращает правильный TreeViewItem.Кто-нибудь сталкивался с этим раньше или знает что-нибудь, на что я могу посмотреть, чтобы помочь решить проблему?

Я запускаю приведенный выше код в событии Loaded TreeView.

Ответы [ 2 ]

7 голосов
/ 04 августа 2010

Я понял, что здесь происходит, ключ в документации MSDN для возвращаемого значения ItemContainerGenerator.ContainerFromItem():

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

Похоже, что когда возвращается ноль, UIElement для элемента еще не создан.

Я обошел это с помощью

tvClientContract.UpdateLayout();

чтобы обновить макет и убедиться, что UIElement существует до вызова

ItemContainerGenerator.ContainerFromItem()
0 голосов
/ 17 октября 2012

Я думаю, что может быть какое-то условие, когда «UpdateLoayout не будет работать»: если TreeView находится в режиме рециркуляции, а элемент не находится в видимой части и / или также в операции «добавления», где создается TreeViewItemв другом потоке.

Решение состоит в том, чтобы использовать аналогичное решение, как я описываю в: WPF: Выберите TreeViewItem, сломанный после корневого уровня

...