views:

65

answers:

1

Hi,

I have a TreeView on my page. It's bound to a collection of clients containing contracts, like:

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; }
}

The XAML for my TreeView is as follows:

<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>

Where ClientContracts is a List<Clients>. The binding works fine and I have a hierarchical grid.

The issue that I'm having is when opening the form with the TreeView on it I want to select the current Client, I currently use the following code:

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

or

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

but this returns inconsistent results, for example I open the form when client 'ABC' is selected and client will be null. I open it again when client 'ABC' is selected and it returns the correct TreeViewItem. Has anyone came across this before or know anything I can look at to help solve the issue?

I run the above code within the Loaded event of the TreeView.

+1  A: 

I figured out what's happening here, the clue is in the MSDN documentation for the return value of ItemContainerGenerator.ContainerFromItem():

A UIElement that corresponds to the given item. Returns null if the item does not belong to the item collection, or if a UIElement has not been generated for it.

It looks like when null is returned, a UIElement hasn't been created for the item yet.

I got round this by using

tvClientContract.UpdateLayout();

to update the layout and ensure a UIElement exists before calling

ItemContainerGenerator.ContainerFromItem()
Fermin