Molts amics quan em troben pel carrer m'aturen i em dieun:
Quan treballo amb un treeView (o un listView) de silverlight i vull obtenir el container d'un node m'apareix l'error: "ContainerFromItem returns null"
Potser penseu que estic fent broma, però fixeu-vos que realment és un error molt habitual:
Anem a solucionar-ho, jo només m'hi he passat 3 hores per trobar quin és el motiu.
I no és un motiu, són dos:
1) En primer lloc, quan des d'un objecte X invoquem el mètode ContainerFromItem només busca els Items fills de l'objecte X.
Solució: Doncs cal invocar ContainerFromItem a l'objecte contenidor pare de l'objecte de negoci del qual volem el contenidor (ContenidorPare.ItemContainerGenerator) . Però, com obting el contenidor del pare? Doncs invocant el mètode ContainerFromItem al seu contenidor pare .... i així fins al node arrel on coneixem el contenidor pare que és conegut: TreeViewX.ItemContainerGenerator. LLavors cal usar recursió:
Public Function ContainerFromItem(ByVal item As objecteDeNegoci) As TreeViewItem
Dim containerThatMightContainItem As TreeViewItem
If IsNothing( item.parent ) Then
containerThatMightContainItem = DirectCast(TreeViewX.ItemContainerGenerator.ContainerFromItem(item), TreeViewItem)
Else
Dim containerItemPare = ContainerFromItem(item.parent)
containerThatMightContainItem = DirectCast(containerItemPare.ItemContainerGenerator.ContainerFromItem(item), TreeViewItem)
End If
Return containerThatMightContainItem
End Function
2) Tot i que ja sabem baixar pels contenidors fins al nostre objecte de negoci, pot ser que encara el seu contenidor sigui Null, a que és degut? Doncs a que FINS QUE NO ES PINTA UN NODE NO SE LI CREA CONTENIDOR. Aleshores cal que estiguis segur que el node s'ha pintat:Solució:
Primer: Expandir el pare:
Dim ccP = ContainerFromItem(objecteDeNegoci.parent)
ccP.IsExpanded = True
ccP.Visibility = Windows.Visibility.Visible
Segon: Forçar que es repinti. (Hi ha solucions alternatives amb events i tal)
ccP.UpdateLayout()
Ara ja estem en condicions de demanar el contenidor del fill:
Dim ccO = ContainerFromItem(objecteDeNegoci)
ccO.IsSelected = True
Si teniu dubtes de que als nodes pares no tinguin contenidor llavors heu de modificar el nostre mètode ContainerFromItem per tal que vagi expandir i fent UpdateLayout dels nodes intermitjos:
Public Function ContainerFromItem(ByVal item As objecteDeNegoci) As TreeViewItem
Dim containerThatMightContainItem As TreeViewItem
If IsNothing( item.parent ) Then
containerThatMightContainItem = DirectCast(TreeViewX.ItemContainerGenerator.ContainerFromItem(item), TreeViewItem)containerThatMightContainItem.IsExpanded = True containerThatMightContainItem.UpdateLayout()
Else
Dim containerItemPare = ContainerFromItem(item.parent)
containerThatMightContainItem = DirectCast(containerItemPare.ItemContainerGenerator.ContainerFromItem(item), TreeViewItem)
End If
Return containerThatMightContainItem
End FunctionBé, espero que ja no us trobeu més amb aquest problema (ni amb l'altre). Si és així, please, deixa un comentari.


Cap comentari:
Publica un comentari a l'entrada