TreeViewItem.ItemContainerGenerator.ContainerFromItem结果不一致

时间:2010-07-29 14:10:47

标签: silverlight treeview silverlight-4.0

我的页面上有一个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; }
}

我的TreeView的XAML如下:

<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的表单时我想选择当前的Client,我目前使用以下代码:

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

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

但这会返回不一致的结果,例如我选择客户端'ABC'时打开表单,客户端将为null。当选择客户端'ABC'并且它返回正确的TreeViewItem时,我再次打开它。有没有人以前遇到过这个或知道我能看到什么来帮助解决这个问题?

我在TreeView的Loaded事件中运行上面的代码。

2 个答案:

答案 0 :(得分:7)

我弄清楚这里发生了什么,关于ItemContainerGenerator.ContainerFromItem()的返回值的MSDN文档中有线索:

  

对应于的UIElement   给定项目。如果项目返回null   不属于该项目   集合,或者如果UIElement没有   为它生成了。

看起来当返回null时,尚未为该项创建UIElement。

我使用

来解决这个问题

tvClientContract.UpdateLayout();

更新布局并确保在调用

之前存在UIElement
ItemContainerGenerator.ContainerFromItem()

答案 1 :(得分:0)

我认为可能存在“UpdateLoayout无效”的情况: 如果TreeView处于回收模式且该项不在可见部分和/或也在“添加”操作中,其中TreeViewItem是在另一个线程上创建的。

解决方案是使用我在下面描述的类似解决方案: WPF: Select TreeViewItem broken past the root level