Newsgroup: it.comp.dotnet
Titolo: Comportamento controllo ListBox WPF Hostato

Ciao a tutti,
ho un problema da cui non riesco ad uscire, spero possiate darmi una mano, 
ammesso che riesca a spiegarmi bene.
In un progetto WinForm di VB.net (2008) ho un controllo ListBox WPF, hostato 
su una Form; questa ListBox utilizza un template per mostrare dei dati, e il 
databinding per "prendere" i dati stessi.
Alla proprieta' ItemsSource del mio ListBox passo un oggetto di tipo 
System.Collections.ObjectModel.ObservableCollection(Of MiaClasse).
La cosa strana e' che quando faccio uno scroll sulla ListBox, gli oggetti 
che vengono mostrati nella porzione di ListBox visibile (e anche qualcuno in 
piu') vengono come "ricreati", quasi come si facesse una New dell'oggetto 
stesso, ma non capisco perche', ne come evitarlo, dato che questo mi porta 
comportamenti non voluti; ho provato a mettere un breakpoint sulla routine 
New, ma questa non viene mai richiamata.
In particolare alcune variabili locali vengono reinizializzate, questo mi 
obbliga ad anare a rileggere dei dati da db, ed ad appesantire 
l'applicazione stessa.
Perche' succede questo?
Ciao e grazie... Maurizio

 Perche' succede questo?
Non so se dico un'eresia, ma forse c'entra il concetto di 
virtualizzazione, cio� il caricamento dei soli dati visibili di un 
controllo, e se non sbaglio la listbox usa un virtualizingstackpanel, ma 
non ci giurerei. Prova a cercare qualcosa sull'argomento, anche se, 
ripeto, � solo la prima cosa che mi � venuta in mente dopo aver letto il 
comportamento che hai descritto

 Perche' succede questo?
condivido quello che dice marco, cosï¿œ a naso potrebbe essere qualcosa 
legato alla virtualizzazione.
Riesci a darci qualche dettaglio in piï¿œ su come ï¿œ fatta la parte wpf?
.m
-- 
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com/profile/mauro
blog @ 
http://milestone.topics.it
whynot [ at ] topics [ dot ] it

Riesci a darci qualche dettaglio in piï¿œ su come ï¿œ fatta la parte wpf?
...
Vi dico tutto cio' che volete, giurin giurello!
Pero' fatemi le domande giuste, altrimenti non saprei cosa dirvi.
Cosa vuoi sapere? 

 Cosa vuoi sapere?
facciamo la cosa piï¿œ semplice, puoi postare un po' di codice?


Non so se dico un'eresia, ma forse c'entra il concetto di
virtualizzazione, cio� il caricamento dei soli dati visibili di un
controllo
...
Si, ho pensato anche io una cosa del genere, quello pero' che non capisco e' 
come vengono recuperati i dati dall'oggetto in questione.
Verra' forse fatta una clonazione in qualche modo?
Boh

facciamo la cosa piï¿œ semplice, puoi postare un po' di codice?
...
Non voglio fare il difficile, ma mi hai chiesto la parte codice Wpf.
Da quel lato faccio solo una assegnazione, alla proprieta' ItemSource della 
ListBox, della mia ObservableCollection(Of MiaClasse)
Non saprei cosa postare, in merito.
Non credo tu voglia vedere lo Xaml del controllo Wpf... o no?
Grazie ancora... Maurizio 


Intanto puoi controllare come � fatta la listbox e se sta usando la 
virtualizzazione, con snoop o wpf inspector:
http://www.wpftutorial.net/inspector.html
vai sulla listbox e vedi se � fatta con un VirtualizingStackPanel, poi 
controlla il valore di IsVirtualizing. Se non sbaglio puoi anche 
modificare il valore al volo e fare una prova (anche se poi mi sa tanto 
che per rileggere il valore cambiato dovresti in qualche modo riaprire 
il controllo e questo rimetterebbe il valore di default...)
Lascia perdere la modifica al volo, comunque puoi controllare appunto 
come � fatto il template di default della listbox.

Mi accodo a me stesso,
ho fatto delle prove ed e' uscito qualche cosa di nuovo, che pero' ancora 
non mi spiego...
Tutto il casotto viene creato da una proprieta', che ho chiamato 
IsTimeAllowed (a seguire, un po' di codice, non preoccupatevi); questa 
proprieta' e' di tipo ReadOnly.
Se modifico la proprieta' e la definisco "normale", cioe' Read/Write, non 
viene piu' scatenato l'inghippo della rilettura del database.
A prima vista si potrebbe pensare che, in una sorta di clonazione messa in 
atto dal virtualizzatore della listbox (mi sono spiegato? spero di si), ci 
sia un passaggio di valori da un oggetto ad un altro attraverso le 
proprieta'.
Il discorso pero' cade andando a leggere il codice; lo incollo qui e poi 
faccio qualche commento
Public ReadOnly Property IsTimeAllowed() As Boolean
  Get
    If Math.Abs(DateDiff(DateInterval.Minute, LastCheckedDate, m_StartsAt)) 
 > 1 Then
      LastCheckedDate = m_StartsAt
      ' se non ho gia' controllato questa data di partenza, faccio il 
controllo
        ' Tagliato : Operazioni di lettura da Database, vengono fatte da 
altre classi e non vedreste nulla
     End If
    Return m_IsTimeAllowed
  End Get
End Property
Come potete vedere, nel caso in cui LastCheckedDate sia diverso da 
m_StartsAt (lo so, avrei potuto usare il Compare di Date, ma ho visto che a 
volte da problemi, magari ne discutiamo in altro thread :-) ), vado a fare 
una serie di operazioni per conoscere il valore di m_IsTimeAllowed, che poi 
e' cio' che la proprieta' IsTimeAllowed deve restituire. Naturalmente in 
queste operazioni c'e' l'accesso al database.
Nelle prove che stavo facendo, il problema era  il LastCheckedDate 
(variabile privata della classe) non conteneva un valore valido, ma era 
inizializzata al valore iniziale delle variabili di tipo Date.
Cambiando la proprieta' da solo lettura a lettura/scrittura, semplicemente 
con
Set(ByVal value As Boolean)
   m_IsTimeAllowed = value
End Se
e naturalmente rimuovendo l'indicazione "ReadOnly", il problema sparisce.
Alquanto strano, non credete anche voi?
Ciao e grazie... Maurizio

Ciao vbMizio,

hai ancora il problema o hai riosolto?


hai ancora il problema o hai riosolto?
...
Il problema e' stato risolto con il metodo descritto, anche se non ho capito 
il perche'. Boh!