Bonjour,

J'ai créé un custom control qui hérite de ItemsControl et dont les données proviennent d'un fichier XML via un XmlDataProvider. Les items sont donc de type XmlNode et les éléments graphiques de type TreeViewItem.

Je voudrais sélectionner un item au moment de l'affichage de mon control. Comme les conteneurs graphiques de chaque item ne sont pas tous construit, j'utilise le ItemContainerGenerator:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public MyItemsControl()
{
    if (this.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
    {   
         EventHandler onStatusChanged = null;

         onStatusChanged = new EventHandler(delegate
         {
              if (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
              {
                   if (this.Items.Count > 0)
                   {      
                        this.ExpandAndSelectItem(this, this.ItemToSelect);

                        this.ItemContainerGenerator.StatusChanged -= onStatusChanged;
                   }
              }         

              this.ItemContainerGenerator.StatusChanged += onStatusChanged;
         });
    }
}
La méthode ExpandAndSelectItem parcours les enfants et utilise également ItemContainerGenerator:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
public bool ExpandAndSelectItem(ItemsControl pParentContainer, XmlNode pItemToSelect)
{
      foreach (object item in pParentContainer.Items)
      {
           TreeViewItem currentContainer = pParentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
 
            XmlNode node1 = item as XmlNode;
            XmlNode node2 = pItemToSelect as XmlNode;
 
            if (      (node1 != null)
                 && (node2 != null)
                 && (XNode.DeepEquals(node1.GetXElement(), node2.GetXElement()))
                 && (currentContainer != null)
               )
            {                    
                    currentContainer.IsSelected = true;
                    currentContainer.BringIntoView();
                    currentContainer.Focus();
 
                    // The item was found.
                    return true;
            }
       }
 
       foreach (Object item in pParentContainer.Items)
       {
           TreeViewItem currentContainer = pParentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
 
            // If children exist.
            if (currentContainer != null && currentContainer.Items.Count > 0)
            {
                // Keeps track of if the TreeViewItem was expanded or not.
                bool wasExpanded = currentContainer.IsExpanded;
 
                // Expands the current TreeViewItem so we can check its child TreeViewItems.
                currentContainer.IsExpanded = true;
 
                // If the TreeViewItem child containers have not been generated, we must listen to the StatusChanged event until they are.
                if (currentContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
                {
                    // Stores the event handler in a variable so we can remove it (in the handler itself).
                    EventHandler onStatusChanged = null;
 
                    onStatusChanged = new EventHandler(delegate
                    {
                        if (currentContainer.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
                        {
                            if (ExpandAndSelectItem(currentContainer, pItemToSelect) == false)
                            {
                                // The assumption is that code executing in this EventHandler is the result of the parent not
                                // being expanded since the containers were not generated.
                                // Since the itemToSelect was not found in the children, collapse the parent since it was previously collapsed.
                                currentContainer.IsExpanded = false;
                             }
 
                              // Removes the StatusChanged event handler since we just handled it (we only needed it once).
                                currentContainer.ItemContainerGenerator.StatusChanged -= onStatusChanged;
                       }
                  });
 
                  currentContainer.ItemContainerGenerator.StatusChanged += onStatusChanged;
              }
              // Otherwise the containers have been generated, so look for item to select in the children.
              else
              {
                   if (ExpandAndSelectItem(currentContainer, pItemToSelect) == false)
                   {
                        // Restores the current TreeViewItem's expanded state.
                        currentContainer.IsExpanded = wasExpanded;
                   }
                   // Otherwise the node was found and selected, so return true.
                   else
                   {
                        return true;
                   }
              }
          }
     }
 
      return false;
}
L'item est bien trouvé, le IsSelected est bien mis à true mais l'item n'est pas sélectionné

Est-ce que je modifie les éléments graphiques trop tôt dans la construction du control ? Je n'arrive pas à comprendre pourquoi mon item n'apparait pas comme sélectionné