Newsgroup: it.comp.lang.visual-basic
Titolo: Problema logico difficile sull'evento click del mouse in un button

Ciao a tutti,
Come al solito sto lavorando con 
vb.net
 2008, ma questa volta ho un
problema di logica logaritmica da risolvere:
Nel mio programma voglio rendere un pulsante a 2 stati (fargli fare 2
cose diverse), fin qui nessun problema. La questione si fa
interessante nel momento in cui il secondo stato deve presentarsi
sempre e solo al click successivo del mouse. Mi spiego: Se clicco il
pulsante "A" (quello che ha 2 stati) poi premo su "B", A da quel
momento in poi deve comportarsi nella stessa maniera del primo click,
mentre se clicco su A, e poi ci clicco nuovamente (senza il
doubleClick) la prima esegue delle operazioni, la seconda altre.
Per adesso al primo click di A faccio partire un timer che intercetta
il Click del mouse, adesso ci sarebbe da capire come fare il
controllo. Il problema più grosso è che la VM intercetta prima
l'evento tick poi il click sul button, quindi prima mi accorgo che è
stato cliccato il pulsante del mouse, poi mi accorgo che il click era
sul pulsante corretto.
Avrei pensato di risolvere con una variabile incrementale che conta i
click sul timer e lo controllo sul button....ma a mio parere è tutto
troppo macchinoso, che ne pensate voi?
Grazie come sempre per le risposte

 doubleClick) la prima esegue delle operazioni, la seconda altre.
Se ho capito bene:
Ti serve una variabile che indichi lo stato di A, ovvero se ï¿œ il primo o  
secondo click.
Ogni click di A cambia il proprio stato.
B resetta lo stato di A.
-- 
Dr. Atlantis

 B resetta lo stato di A.
In questo caso, potrebbe essere comodo fare un piccolo controllo
derivato da Button, ad esempio:
Imports System.ComponentModel
Public Class StateButton
   Inherits Button
   Private mStateON As Boolean
   <Browsable(False)> Public Property StateON() As Boolean
      Get
         Return mStateON
      End Get
      Set(ByVal value As Boolean)
         mStateON = value
      End Set
   End Property
   Public Sub ToggleState()
      StateON = Not StateON
   End Sub
   Public Sub ResetState()
      StateON = False
   End Sub
   Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
      ToggleState()
      MyBase.OnClick(e)
   End Sub
End Class
A questo punto, definendo il pulsante A di tipo StateButton, il cambio
di stato è gestito implicitamente tramite l'Override qui sopra, ed è
sufficente solo testare la property StateON; il pulsante B può essere
anche un Button standard, che deve semplicemente invocare .ResetState
'Form con uno StateButton e un Button, rispettivamente buttonA e
buttonB
Public Class Form1
   Private Sub buttonA_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles buttonA.Click
      If buttonA.StateON Then
         Me.BackColor = Color.Green
      Else
         Me.BackColor = Color.Red
      End If
      Me.Text = Now.ToString
   End Sub
   Private Sub buttonB_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles buttonB.Click
      buttonA.ResetState()
   End Sub
End Class
Se il reset dello stato deve essere fatto non da un pulsante
particolare, ma da un *qualunque* pulsante, ovvero lo stato si deve
resettare alla pressione di qualunque altro pulsante che non sia A
stesso, allora la cosa si complica un po'.... un primo approccio
potrebbe essere quello di intercettare gli eventi degli altri pulsanti
tramite un delegato messo in StateButton; per esempio cosi'.
'Aggiungere a StateButton
   Public Sub ResetStateHandler(ByVal sender As Object, ByVal e As
EventArgs)
      ResetState()
   End Sub
'La form di test diventa ora
Public Class Form1
   Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
      AddHandler buttonB.Click, AddressOf buttonA.ResetStateHandler
      AddHandler Buttonc.Click, AddressOf buttonA.ResetStateHandler
      AddHandler Buttond.Click, AddressOf buttonA.ResetStateHandler
      AddHandler Buttone.Click, AddressOf buttonA.ResetStateHandler
   End Sub
   Private Sub buttonA_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles buttonA.Click
      If buttonA.StateON Then
         Me.BackColor = Color.Green
      Else
         Me.BackColor = Color.Red
      End If
      Me.Text = Now.ToString
   End Sub
   Private Sub buttonB_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles buttonB.Click
      'questo per mostrare che l'evento Click può avere più di un
handler;
      'qui eseguiamo il codice sopecifico di B, ma contemporaneamente
viene invocato
      'ResetStateHandler di A
      buttonB.Text = Now.ToString
   End Sub
End Class


(SNIP)
Complimenti per lo sfoggio di OOP, ma il problema io lo risolvevo "alla  
vecchia" con tre linee di codice...
-- 
Dr. Atlantis

 vecchia" con tre linee di codice...
Non ne dubito... anzi, dai, facciamo 7 compresa l'intestazione delle
funzioni:
   Dim flag As Boolean
   Private Sub Button1_Click(...) Handles Button1.Click
      flag = Not flag
   End Sub
   Private Sub Button2_Click(...) Handles Button2.Click
      flag = False
   End Sub
Però mi sembra un tantino strano che si sia messo a scomodare timer
per monitorare i click ecc. se davvero la questione fosse così banale,
e limitata ad un singolo caso; sospetto che il suo problema fosse un
pelo più generico ed esteso...


Ciao, grazie a tutti per le riposte.
Esatto, Il problema è più generico perchè devo resettare lo stato del
pulsante in tutti i casi in cui
ho l'evento click del mouse tranne ovviamente nel click dello stesso
pulsante.
Per quanto riguarda l'ereditarietà vale quanto detto sopra.
Grazie ancora.