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 Function2) 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 Function
Bé, 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