我的页面上有一个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事件中运行上面的代码。
答案 0 :(得分:7)
我弄清楚这里发生了什么,关于ItemContainerGenerator.ContainerFromItem()
的返回值的MSDN文档中有线索:
对应于的UIElement 给定项目。如果项目返回null 不属于该项目 集合,或者如果UIElement没有 为它生成了。
看起来当返回null时,尚未为该项创建UIElement。
我使用
来解决这个问题 tvClientContract.UpdateLayout();
更新布局并确保在调用
之前存在UIElementItemContainerGenerator.ContainerFromItem()
答案 1 :(得分:0)
我认为可能存在“UpdateLoayout无效”的情况: 如果TreeView处于回收模式且该项不在可见部分和/或也在“添加”操作中,其中TreeViewItem是在另一个线程上创建的。
解决方案是使用我在下面描述的类似解决方案: WPF: Select TreeViewItem broken past the root level