User Control - Ereditarietà

martedì 29 giugno 2010 - 12.55

bobosassa Profilo | Newbie

Ciao,sono Roberto,
sono alle prime armi con vb.net e vorrei porvi una domanda:

Ho creato un semplice user control VALUEBUTTON che eredita da button.
Ho gestito l'evento click di VALUEBUTTON in questo modo:

Private Sub ValueButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Click
MessageBox.Show("Padre")
End Sub

Dopodichè,ho creato una semplice windows form,in cui ho aggiunto un VALUEBUTTON e nel click di tale
pulsante personalizzato ho inserito questo codice:

Private Sub ValueButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ValueButton1.Click
Label1.Text = CStr(ValueButton1.ButtonValue)
MessageBox.Show("Figlio")
End Sub

Ovviamente,lanciando l'applicazione e cliccando sul pulsante,mi appariranno nell'ordine,la messagebox della classe padre
e poi la messagebox della classe figlio.
Qualcuno potrebbe dirmi come far eseguire prima il codice presente nel click della classe figlio e poi quello presente nel
click della classe padre?
Con Visual foxpro,utilizzando DODEFAULT() ,la cosa è molto semplice.

Grazie a tutti.

aiedail92 Profilo | Expert

Ciao

Secondo me hai sbagliato approccio, gli eventi vanno usati per notificare gli utenti esterni alla tua classe; per l'uso interno invece dovresti eseguire l'override delle funzioni che generano l'evento, nel nostro caso OnClick:

' Nella classe ValueButton: Protected Overrides Sub OnClick(ByVal e As EventArgs) ' Decidi se prima mostrare la MessageBox oppure prima sollevare l'evento OnClick ' In questo caso apparirà prima questa MessageBox, poi quella della Form MessageBox.Show("In ValueButton::OnClick") MyBase.OnClick(e) End Sub

Se ci sono problemi nel codice fammi sapere perché l'ho scritto al volo

Luca

bobosassa Profilo | Newbie

Ciao,mi sei stato molto d'aiuto.
Però,mi sorge una domanda:
con il codice che tu mi hai dato,devo decidere a priori (ovvero nella classe padre)
l'ordine di esecuzione tra codice ereditato e codice aggiuntivo,mentre sarebbe
utile poter fare tale scelta dopo aver aggiunto il pulsante alla form.
Non so se riesco a spiegarmi.

aiedail92 Profilo | Expert

A questo punto ti conviene usare gli eventi MouseDown, MouseClick e MouseUp, che vengono generati, rispettivamente, prima del click, al momento del click e dopo il click.

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mouseclick

Luca

bobosassa Profilo | Newbie

Ciao,
ma io non parlo dell'evento click,ma di un generico evento.
Ovvero,se io ho del codice in un evento dello user control,
non c'è alcun modo,una volta,inserito tale controllo in una form,
di decidere se eseguirlo o meno ed in caso affermativo,quando?
In altre parole,in visual foxpro,per eseguire il codice della classe
sorgente,mi bastava effettuare dodefault() e quindi tale riga potevo
metterla dove volevo o potevo anche non metterla.

aiedail92 Profilo | Expert

Se ho capito bene come funziona, anche in Visual FoxPro funziona allo stesso modo: il DODEFAULT() lo puoi usare in una classe derivata per chiamare la funzione corrispondente nella classe padre, in pratica corrisponde al MyBase.OnClick...

Se è così (ma potrei sbagliarmi), quindi, anche in Visual FoxPro non puoi scegliere "dopo averla messa nel form", ma solo quando implementi la classe derivata (nel tuo caso la ValueButton).

Se invece non è così, l'unica cosa che puoi fare è esporre un metodo pubblico da richiamare quando decidi tu:

Class ValueButton Inherits Button Public Sub DoWork() MessageBox.Show("DoWork!") End Sub End Class
' In TuaForm.tuoValueButton_Click: If condizione Then tuoValueButton.DoWork() End If

Luca

bobosassa Profilo | Newbie

Ecco cosa fa il DODEFAULT():

if you place DODEFAULT( ) in the Click event of a subclass, Visual FoxPro executes the Click event of the parent class.

Ed è proprio ciò che vorrei fare io.
Creare il mio bottone personalizzato (user control) e mettere un determinato codice nell'evento click.
Dopodichè,creare una form vuota,inserire lo user control,andare nell'evento click e decidere (con qualcosa di analogo al
DODEFAULT() ) se eseguire o meno il codice della classe parent.
Mentre da quanto ho capito,con Visual Studio si ragiona al contrario,ovvero nella classe parent devo mettere il mybase.

aiedail92 Profilo | Expert

No, temo tu stia facendo confusione fra subclass e parent class... La subclass è la classe derivata, la parent class è la classe base.

Da come è scritto lì il DODEFAULTS() del Visual FoxPro è esattamente il corrispettivo del MyBase.Funzione: nella classe derivata inserisci il DODEFAULTS() per eseguire il codice "di default" (appunto) stabilito dalla classe base. Stessa identica cosa in VB.Net: la classe base crea una funzione e una implementazione "di default", quindi la classe derivata esegue l'override e sceglie se e quando chiamare la funzione della classe base.

Quello che non puoi fare è sceglierlo "dopo" aver creato la classe derivata, cioè quando vai ad inserire il controllo nella form, lì non stai più definendo la classe, la stai già usando, quindi non puoi decidere lì nel gestore eventi dalla form se eseguire o no il codice, verrà fatto esattamente quanto stabilito nella classe derivata.

Spero di essere stato chiaro

Luca

bobosassa Profilo | Newbie

No,scusami,la differenza tra parent e sub class mi è chiara,credimi.
Provo a spiegarmi meglio.Scusa se prendo come esempio ciò che faccio in visual fox pro.
Allora:

1) Creo una classe based on CommandButton.Quindi,sto creando un bottone personalizzato.

2) Vado nel metodo click e scrivo semplicemente messagebox("Padre").

3) Compilo e salvo la classe.

4) Creo un progetto con una singola form ed aggiungo la classe precedentemente salvata;
in questo modo posso aggiungere alla form il mio bottone personalizzato e così faccio.

5) Eseguo il progetto e giustamente cliccando non succede nulla.

6) Ora,vado nel click del bottone appena inserito e scrivo:

DODEFAULT()
messagebox("Figlio")

Adesso,al click del pulsante,mi appariranno in ordine i messaggi "Padre" "Figlio"

7) Se,invece,nel click del bottone inserito sulla form,scrivo:

messagebox("Figlio")
DODEFAULT()

al click,mi appariranno in ordine i messaggi "Figlio" "Padre"

E questo credo sia il comportamento corretto,ovvero nella classe parent io decido un comportamento standard per il click del mio
pulsante personalizzato,poi quando utilizzerò tale bottone sarò io a decidere se voler eseguire il comportamento standard,o se
non lo voglio eseguire,o se voglio esguirlo prima/dopo di qualcos altro.

aiedail92 Profilo | Expert

Allora come dicevo qualche post fa, l'unica cosa che puoi fare è inserire un metodo da chiamare quando vuoi tu:

Class ValueButton Inherits Button Public Sub DoDefaultClick() MessageBox.Show("Padre!") End Sub End Class

Private Sub tuoValueButton_Click(sender As Object, e As EventArgs) _ Handles tuoValueButton.Click CType(sender, ValueButton).DoDefaultClick() MessageBox.Show("Figlio!") End Sub

Luca

bobosassa Profilo | Newbie

Si,effettivamente sembra che sia l'unica strada,anche se la cosa è un pò strana.

aiedail92 Profilo | Expert

Potrei dire la stessa cosa per quanto riguarda Visual FoxPro... Mi sembra strano che una classe definisca un'azione da compiere di default e poi non venga compiuta se non su esplicita richiesta. Ok finché ciò avviene "dall'interno", cioè dalle classi derivate, che fornendo una nuova implementazione possano decidere di non aver bisogno di quella di default, però mi sembra strano che ciò accada anche per gli "utenti esterni" di tale classe.

Si tratta comunque di due strumenti diversi, con caratteristiche diverse, e non conoscendo Visual FoxPro non posso sapere il razionale che ci sta dietro...

Comunque l'importante è che il problema sia risolto

Luca

bobosassa Profilo | Newbie

Si,solo un'ultima cosa,scusami.
Il codice che mi hai fornito mi da errore e mi sottolinea ValueButton,nel codice che inizi con ctype.

Ho risolto con:

Me.btnValueButton.DoDefaultClick()

Scusa,ultima cosa,e non ti do più fastidio.
cosa intendi per utenti esterni e interni?

aiedail92 Profilo | Expert

Con "utenti interni" intendo la classe stessa, o una delle sue classi derivate, con "utenti esterni" invece intendo chiunque crei un'istanza della classe (o di una delle sue derivate) per utilizzarla, quindi ad esempio il tuo Form è un "utente esterno"

Luca

bobosassa Profilo | Newbie

Perfetto,grazie mille per l'aiuto.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5