Newsgroup: it.comp.lang.visual-basic
Titolo: deckeccare nodo?

ciao a tutti
penso sia una sciocchezuola, ma non ci riesco
devo dececcare un determinato nodo di una treeview
lasciando stare la casistica specifica, perchè se scrivo così non
 funziona?
If Node.Checked = True Then Node.Checked = False
:o
-- 
In sardegna è pieno di ladri: 
http://tinyurl.com/s2pq9
******************************************************
http://x-privat.org
 - 
http://tinyurl.com/4y7aa
******************************************************

 
cmq a me server ceccare e controllare e dececcare se non si sono
 verificate alcune condizioni
ho visto che se cerco di dececcare da fuori lo fa, mentre al momento
 del click no
per risolvere volevo quindi fare una funzione che giri dopo che sia
 finito l'evento check... 
č la via giusta?
-- 
In sardegna č pieno di ladri: 
http://tinyurl.com/s2pq9


 If Node.Checked = True Then Node.Checked = False
Hai guardato l'evento BeforeCheck?
Ciao 

 
ciao, grazie per la dritta, ma non lo trovo
c'č in vb6?
-- 
In sardegna č pieno di ladri: 
http://tinyurl.com/s2pq9


 
anche su google non ho trovato nulla :o
-- 


 anche su google non ho trovato nulla :o
Non capisco quale sia il problema.
Se vuoi smarcare da codice il nodo di un treeview in effetti basta che 
imposti il relativo Checked a False, provato ora e funziona normalmente.
Sei sicuro il problema non sia da un'altra parte? Non e' che ti e' rimasto 
un on error resume next aperto da qualche parte?
Nel caso, verifica il contenuto della variabile err subito dopo quell'if

 normalmente.
Il problema, a quanto ho capito, è che se setta Checked=False *negli eventi
NodeClick o NodeCheck*, poi però il nodo rimane comunque "checkato".
Mi ci sono scontrato anch'io e l'ho dovuto bypassare con un sistema un po'
macchinoso (che non riporto qui se non richiesto), ma sicuramente esisteranno
dei workaround più eleganti (es. con il subclassing).
Bye
Raf

 
esatto è questo il problema
praticamente devo fare un accrocchio per far selezionare solo x voci da
 una lista (ma solo x se sono certi id, non x in generale)
quindi semplicemente, facendo il mio controllo, al ceck, volevo
 dececcare l'ultima ceccata ed avvisare, se si supera il numero massimo
 di quelle voci
attualmente ho risolto dececcando un'altra voce tra quelle ceccate, ma
 non è una soluzione molto bella, dato che l'utente potrebbe non
 accorgersi che gli ho dececcato una voce :p che è posizionata chissà
 dove
mentre dececcare la voce appena cliccata salta subito all'occhio
se la soluzione tua non è un papiro di codice e non devo usare api o
 cose che potrebbero non funzionare senza ridistribuire tutto il
 pacchetto, bè prova a postarmela :)
-- 
In sardegna è pieno di ladri: 
http://tinyurl.com/s2pq9


 dei workaround piů eleganti (es. con il subclassing).
E' vero, non funziona.
Un sistema stupido č mettere un timer e controllare da lě i vari checks.
Magari disabilitando il timer quando ha finito il controllo e riabilitandolo 
ai vari check sugli items.
Ciao 

 mentre dececcare la voce appena cliccata salta subito all'occhio
Allora direi di fare così che mi pare più chiaro anche per l'utente: primo 
gli metti scritto che può ceccarne solo n, e magari al check gli mostri 
quanti sono quelli checcati, quando l'utente conferma se ha superato il 
limite glielo dici con una messagebox e non lo fai proseguire.
Ciao 

  pacchetto, bè prova a postarmela :)
Non, non c'è nulla di strano, a parte l'API SendMessage che viene chiamata in
una funzione che indica se il cursore si trova sopra il checkbox del nodo oppure
no. Altrimenti la segnalazione che eventualmente appare quando il nodo non è
checkabile viene mostrata anche quando si clicca sulla didascalia del nodo e non
sulla casella.
Nel form occorre gestire gli eventi MouseDown (per salvare un "riferimento" al
nodo quando si clicca sulla checkbox di un nodo non checkabile) e MouseUp (per
resettare la proprietà Checked del nodo salvato)
Detta tvw la TreeView:
Private Sub tvw_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As
Single)
Dim Node As Node
    If Button = vbLeftButton Then
        Set Node = tvw.HitTest(X, Y)
        If TreeViewHitTest(tvw, X, Y) = tvwHitOnItemStateIcon Then
            If Not NodeCheckable(Node) Then    '<--- Sostituisci con il test che
ti riguarda
                tvw.Tag = Node.Index                ' Usa il Tag del TV per
memorizzare un rif. al nodo da decheckare
            End If
        End If
    End If
End Sub
Private Sub tvw_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As
Single)
    If tvw.Tag <> "" Then
        Beep    ' O altra segnalazione
        tvw.Nodes(Val(tvw.Tag)).Checked = False
        tvw.Tag = ""
    End If
End Sub
Poi aggiungi 'sta roba in un modulo BAS:
Private Const TV_FIRST = &H1100&
Private Const TVM_HITTEST = (TV_FIRST + 17)
Private Type POINTAPI
    X As Long
    Y As Long
End Type
Private Type TVHITTESTINFO
    pt      As POINTAPI
    flags   As Integer
    hItem   As Long
End Type
Private Const TVHT_ONITEMSTATEICON = &H40
Public Enum TreeViewHitTestFlags
    tvwHitOnItemStateIcon = TVHT_ONITEMSTATEICON
    '... altre costanti qui non servono
End Enum
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal
hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Function TreeViewHitTest(tvw As TreeView, ByVal X As Single, ByVal Y As
Single) As TreeViewHitTestFlags
Dim tvhti As TVHITTESTINFO
    With 
tvhti.pt
        .X = X \ Screen.TwipsPerPixelX
        .Y = Y \ Screen.TwipsPerPixelY
    End With
    If SendMessage(tvw.hwnd, TVM_HITTEST, 0, tvhti) <> 0 Then
        TreeViewHitTest = tvhti.flags
    End If
End Function
HTH
Ciao
Raf

 
purtroppo sto modificando un content management, uno di quei polpettoni
 di programmi fatti apposta per essere rivenduti e quindi con codice
 non ottimizzato per il singolo caso ma un puttanaio di roba che non
 immagini :)
moduli e moduli riciclati oltre ogni limite, funzioni che richiamano
 funzioni
una caccia al tesoro insomma
quindi quella schermatina preferivo non toccarla graficamente, anche
 perchč come spazio sono molto tirato e non so se viene usata anche in
 altre occasioni (ci metto meno a fare il trucco del timer che a
 scoprirlo in quell'inferno :p)
-- 


 mentre dececcare la voce appena cliccata salta subito all'occhio
Ah, ho capito, e' una banalita'.
Nel NodeCheck registri, in una variabile di modulo, la .Index del nodo 
selezionato (dovrebbe essere piu' veloce della .Key, in ogni caso registri 
solo un Integer e non una stringa)
Nel MouseUp fai la verifica se ci sono troppi nodi selezionati e nel caso 
tramite il valore di .Index che ti sei segnato prima raggiungi l'ultimo nodo 
e lo smarchi.
Funziona, garantisco.

 
grazie 1000 per il codice, però preferivo non usare api
mi hai dato cmq una dritta con il mouse
forse usando la mousemove
prima al ceck faccio il controllo, se è errato memorizzo l'id della
 check
poi col mousemove, lancio la funzione
se c'è da sceccare, scecco e azzero e avviso
ora provo, mi sembra la soluzione più veloce... spero non ci siano
 complicazioni
-- 


 Funziona, garantisco.
grassie 1000
provo perň con il mousemove, perchč con l'up bisogna cliccare, no?
quindi dovrei memorizzare quando raggiungo il limite e poi rifare il
 controllo col mouse up
mentre con la mousemove, dopo il check, muovo e se ho superato il
 numero avviso e tolgo
giusto? :p
-- 


 
mmm, come non detto :)
non ho ben capito il motivo, ma cliccando un po' a caso ogni tanto
 riesco a superare il numero massimo di check


 giusto? :p
De gustibus, io preferisco semplicemente non inserire codice nel MouseMove 
se non strettamente necessario.
E per evitare il check di un nodo, da un punto di vista logico,mi pare piu' 
corretto intervenire quando l'utente marca il nodo piuttosto che quando 
muove il mouse.
Ma sono pippe mentali mie.

  complicazioni
Non avevo pensato che il test si poteva fare direttamente nell'evento NodeCheck
(grazie a drizzt)!
Quindi non serve chiamare l'API:
Private Sub tvw_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As
Single)
    If tvw.Tag <> "" Then
        Beep
        tvw.Nodes(Val(tvw.Tag)).Checked = False
        tvw.Tag = ""
    End If
End Sub
Private Sub tvw_NodeCheck(ByVal Node As MSComctlLib.Node)
    If Not NodeCheckable(Node) Then
        tvw.Tag = Node.Index
    End If
End Sub
Bye
Raf

 
c'č perň qualcosa che non va
l'ho messo anche nell'azione mouse up, perň cliccando molto veloce mi
 perdo salta ogni tanto il controllo
forse posso risolvere mettendo l'alert, cosě evito i click a raffica
-- 


 forse posso risolvere mettendo l'alert, cosě evito i click a raffica
Mi rimangio quello che ho detto prima: se torni alla mia soluzione originaria
(MouseDown/MouseUp) funziona anche se clicchi come un telegrafista impazzito...
Anche senza chiamare API (non ho poi capito cos'č che ti impedisce di
usarle...):
Private Sub tvw_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As
Single)
Dim Node    As Node
    If Button = vbLeftButton Then
        Set Node = tvw.HitTest(X, Y)
        If Not Node Is Nothing Then    '<--- Questo test serve perché se clicchi
non su un nodo non deve far nulla
        'If TreeViewHitTest(tvw, X, Y) = tvwHitOnItemStateIcon Then
            If Not NodeCheckable(Node) Then
                tvw.Tag = Node.Index
            End If
        End If
    End If
End Sub
Private Sub tvw_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As
Single)
    If tvw.Tag <> "" Then
        Beep
        tvw.Nodes(Val(tvw.Tag)).Checked = False
        tvw.Tag = ""
    End If
End Sub
Bye
Raf