Problema con constructor New

sabato 24 gennaio 2009 - 13.49

ans66 Profilo | Junior Member

Sto cimentandomi per la prima volta con un constructor New: non funziona e vorrei capire il motivo. Ho visto un po' di esempi ma non riesco a trovare l'errore.

Public Structure ValoriChart
Public Larghezza As Double
Public Altezza As Double
Public Shared Titolo As String = "Grafico"
Public ColoreBordo As System.Drawing.Color
Public ColoreCarattere As System.Drawing.Color
Public TipoCarattere As Drawing.Font

' constructor

Public Sub New( _
ByVal Tp_Car As System.Drawing.Font)
Tp_Car = TipoCarattere
End Sub 'New

Public Property TipoCaratter() As Drawing.Font
Get
Return TipoCarattere
End Get
Set(ByVal Value As Drawing.Font)
TipoCarattere = Value
End Set
End Property

End Structure

chart1.Titles(0).Font = New ValoriChart(????) errore

Jeremy Profilo | Guru

Guarda un pò cosa hai scritto qui:

>Public Sub New( _
>ByVal Tp_Car As System.Drawing.Font)
>Tp_Car = TipoCarattere
>End Sub 'New

Quando usi un costruttore, il parametro che dichiari nella firma, deve essere un valore di assegnazione e non la destinazione di una assegnazione....quindi:

Public Sub New( _
ByVal Tp_Car As System.Drawing.Font)
TipoCarattere =Tp_Car
End Sub

Se poi vogliamo discutere sulla visibilità delle variabili.....ci sarebbe da dire qualcosina...presta un pò più di attenzione nelle dichiarazioni delle variabili, e dichiara pubbliche solo quelle che realmente hai necessità che lo siano.....
Esistono anche le dichiarazioni Protected e Private che andrebbero usate in base alle eigenze.
Sembra una precisazione inutile, ma ti garantisco che non lo è!!!

Facci sapere ....
Ciao

ans66 Profilo | Junior Member

Jeremy,

Grazie per la risposta. Ho cambiato come mi hai detto ma non riesco a richiamare il constructor New con
chart1.Titles(0).Font = New ValoriChart(???). Il preoblema sta nel tipo di variabili?


Public TipoCarattere As Drawing.Font

' constructor
Public Sub New( _
ByVal Tp_Car As System.Drawing.Font)
TipoCarattere = Tp_Car
End Sub 'New

Public Property TipoCaratter() As Drawing.Font
Get
Return TipoCarattere
End Get
Set(ByVal Value As Drawing.Font)
TipoCarattere = Value
End Set
End Property

End Structure

Jeremy Profilo | Guru

Se ho capito bene...tu vuoi sapere cosa devi scrivere dove hai messo i punti interrogativi....giusto???

Se è così...devi creare un nuovo oggetto Font valorizzandone le proprietà per ottenere il formato che ti interessa....

Private mioFont as system.Drawing.Font
miofont=New System.Drawing.Font("Tahoma", 12.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))

chart1.Titles(0).Font = New ValoriChart(miofont).

Facci sapere.....

Ciao


[edit]
Pensandoci bene, comunque, c'è ancora qualcosa che non quadra...
Non capisco il senso di chart1.Titles(0).Font=New Valorichart(miofont)...a meno che ValoriChart non erediti da System.Drawing.Font...il che non avrebbe senso con il fatto di dichiarare nella firma del costruttore un parametro di tipo Font......e comunque dovrebbe diventare una classe e non una struttura(sono due cose diverse)
Io vedrei giusto fare chart1.Titles(0).Font=miofont....quindi forse non ho capito cosa vuoi ottenere, e magari tu ti stai incartando su cose che non servono!!!!
Forse se spieghi meglio riusciamo a ragionarci insieme....

Ciao....
[endedit]

ans66 Profilo | Junior Member

Sono arrivato a questa conclusione:

Dim miofont As Drawing.Font
miofont = New Drawing.Font("Arial", 12, Drawing.FontStyle.Bold)
chart1.Titles(0).Font = New Chart.ValoriChart(miofont).TipoCarattere

o meglio miofont passato attraverso la Sub routine:

Private Sub StampaChart(ByVal valorichart As Chart.ValoriChart, ByVal miofont As Drawing.Font)
chart1.Titles(0).Font = New Chart.ValoriChart(miofont).TipoCarattere

------------------------------------------------

Scusami Jeremi, hai ragione meglio che spieghi quello che intendo fare. Sto creando una classe all'interno della quale ho creato una Sub routine alla quale passare tutti i valori per creare immagine jpg che mostra una chart (utilizzando OpenFlashChart). Uno dei valori da passare e` il font del titolo richiesto come New Font. Ho creato una struttura ValoriChart con la quale passo tutti i valori alla Sub routine StampaChart. L'approccio forse non e` corretto. Sotto alcune righe per spiegarti meglio cosa vorrei fare. (considera che normalmente il vaore font viene passato in questo modo "Chart1.Titles(0).Font = New Font("Arial", 12, FontStyle.Bold)" )


Public Class Chart
Inherits Windows.Forms.DataVisualization.Charting.Chart
Private chart1 As Windows.Forms.DataVisualization.Charting.Chart



Private Sub StampaChart(ByVal valorichart As ValoriChart)

chart1.Width = valorichart.Larghezza
chart1.Height = valorichart.Altezza

chart1.Titles.Add(valorichart.Titolo)
chart1.Titles(0).BorderColor = valorichart.ColoreBordo
chart1.Titles(0).ForeColor = valorichart.ColoreCarattere
chart1.Titles(0).Font = New ValoriChart(???)

Jeremy Profilo | Guru

Ciao Ans....
Mi sembra che tu stia facendo il classico errore di chi, venendo a conoscenza di una nuova tecnica di programmazione, voglia per forza utilizzarla senza sapere, effettivamente, se lo scenario in cui si trova, possa davvero permetterne l'utilizzo o quanto meno non scombini completamente lo scenario stesso.

Cominciamo da qui:

Qui dichiari una classe Pubblica che si chiama Chart....
Nel .NET Framework, esiste già una classe con questo nome, quindi non sarebbe proprio giusto che tu ti 'appropri' di questo nome, piuttosto, chiamala MyChart(e poi ti spiego perchè)
>Public Class Chart
Qui,invece, fai in modo che la tua classe, erediti dal tipo Windows.Forms.DataVisualization.Charting.Chart...e fin qui va bene...il motivo per cui ti ho consigliato di cambiare il nome in MyChart, è proprio questo....non vorrei ti confondessi quando decidi di istanziare nella tua applicazione un nuovo oggetto di tipo 'Chart' o di tipo 'Chart'
>Inherits Windows.Forms.DataVisualization.Charting.Chart
Qui, invece, dichiari un oggetto dello stesso tipo dal quale stai ereditando tutte le proprietà ed i metodi...e questo NON ha nessun senso, in quanto, la tua classe, è già tipizzata Windows.Forms.DataVisualization.Charting.Chart....quindi, a differenza di alcuni casi particolari, questo non ha senso.
>Private chart1 As Windows.Forms.DataVisualization.Charting.Chart
Qui, dichiari un nuovo metodo 'StampaChart' che, nella classe originale, non esiste, quindi questo ha un senso, perchè stai creando un controllo(o componente che sia) personalizzato, che ha disponibili tutte le proprietà e metodi che hai ereditato dal tipo 'Chart', più il tuo metodo StampaChart.
In più, hai deciso, di firmare il metodo con un parametro tipizzato come 'ValoriChart' che non esiste in natura, quindi, è necessario che tu lo dichiari all'interno della tua classe con visibilità pubblica, in modo che, in qualsiasi applicazione tu lo voglia utilizzare, hai disponibile anche ciò che serve per usare il metodo StampaChart.
>Private Sub StampaChart(ByVal valorichart As ValoriChart)
Da qui in poi, valorizzi tutte le proprietà che ti servono per rendere l'aspetto del 'tuo controllo' come ti serve....nota che ho evidenziato 'TUO CONTROLLO' per farti notare che hai già un controllo di tipo Chart, quindi....
>Me.Width = valorichart.Larghezza
>Me.Height = valorichart.Altezza
>Me.Titles.Add(valorichart.Titolo)
>Me.Titles(0).BorderColor = valorichart.ColoreBordo
>Me.Titles(0).ForeColor = valorichart.ColoreCaratte
Qui, vuoi assegnare il Font specificato nel parametro del costruttore.....ma, a mio avviso, il costruttore, così come l'hai usato tu, in questo scenario, non va bene.....basterebbe aggiungere un'altro parametro nella firma del metodo, visto che,Tipocarattere la utilizzi solo a scopo di stampare il Chart.
altrimenti.....andrebbe rivista un'attimo tutta la struttura della tua classe.
>Me.Titles(0).Font = TipoCarattere
>End Sub

>Public Structure ValoriChart
>Public Larghezza As Double
>Public Altezza As Double
Qui, non ha senso che tu decori la variabile Titolo con l'attributo Shared(condivisa)....con chi??...e perchè???
>Public Shared Titolo As String = "Grafico"
>Public ColoreBordo As System.Drawing.Color
>Public ColoreCarattere As System.Drawing.Color
Questa variabile non ha senso, invece, che venga dichiarata Public, perchè è di supporto alla proprietà TipoCaratter che è gia di per sè pubblica.
Quindi diventerebbe Private TipoCarattere as Drawing.Font.
Io, di solito, faccio così:
Private _TipoCarattere as Drawing.Font....così mi ricordo che _TipoCarattere è 'l'appoggio' della proprietà TipoCarattere
>Public TipoCarattere As Drawing.Font

>Public Sub New( _
>ByVal Tp_Car As System.Drawing.Font)
Qui, come abbiamo già detto, diventa TipoCarattere=Tp_Car(il perchè te l'ho già spiegato)
>Tp_Car = TipoCarattere
>End Sub 'New

>Public Property TipoCaratter() As Drawing.Font
>Get
>Return TipoCarattere
>End Get
>Set(ByVal Value As Drawing.Font)
>TipoCarattere = Value
>End Set
>End Property
>End Structure

Spero di non aver dimenticato nulla e di essere stato abbastanza chiaro...in caso contrario, fatti sentire..(magari se qualche guru passa di qua...sono abbastanza umile(fate pure le vostre considerazioni))

Facci sapere...
Ciao

Jeremy Profilo | Guru

Ti rispondo qui perchè nell'altro thread mi restituisce un errore del server
==============================================================
Ciao Ans66.
Già in altre occasioni, mi è sembrato che tu avessi un pò di confusione in testa riguardo l'uso di classi,strutture e costruttori.
Vediamo se riusciamo a fare un pò di chiarezza ......
In questo caso, l'errore è lampante

>Private Sub PrintDocument_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument.PrintPage

Qui sotto, dichiari una nuova istanza della tua classe InsTitolo
>Dim inSTit As New WindowsApplication1.InsTitolo

Qui ne usi le proprietà che non sono le stesse di quelle valorizzate nell'evento click del button, pertanto, InSTit è e sarà sempre vuoto in quanto nuovo.
>Dim Fn As New System.Drawing.Font(inSTit.TipoFont, inSTit.GrandezzaFont, inSTit.StileFont)
>e.Graphics.DrawString(inSTit.Titolo, Fn, inSTit.Colore, inSTit.x, inSTit.y)
End Sub

Per risolvere il tuo problema, così come hai strutturato il tuo progetto, devi creare un overloads del sodtruttore, la quale firma, richiederà un parametro di tipo InsTitolo.
Quindi, nella classe MiaStampa, devi scrivere questo codice:
private InsTit Public sub new(byval _instit as InsTitolo) InsTit=_instit End Sub

E nell'evento printpage della tua classe MiaStampa, devi eliminare la dichiarazione dell'oggetto InsTit
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Come avrai notato, ho semplicemente cancellato la riga di dichiarazione di nuova istanza dell'oggetto inSTit con visibilità a livello del metodo, cosi chè inSTit.x, inSTit.y,etc, potessero fare riferimento ad InsTit con visibilità a livello di classe il quale,grazie al costruttore, a preso il riferimento all'oggetto che hai valorizzato nell'evento click del button.
Forse, al momento ti sembra di non aver ancora chiare le idee.....tu prova se così risolvi, dopo eventualmente passiamo a qualche spiegazione in più.
Basta che non scappi come hai fatto l'ultima volta che ti ho risposto... ..
http://www.dotnethell.it/forum/messages.aspx?ThreadID=28294
Forse, se avessi prestato attenzione a quanto ti risposi, avresti avuto le idee un pò più chiare...o forse no....fatto stà che avresti potuto replicare

Facci sapere..
Ciao

ans66 Profilo | Junior Member

Jeremy,

Penso di aver capito l'errore. Ho modificato in questo modo:

Private InsTit As InsTitolo
Public Sub New(ByVal _instit)
InsTit = _instit
End Sub

Nel form ho modificato:

Dim InPr As New WindowsApplication1.InsTitolo
InPr.x = 250
InPr.y = 50
InPr.TipoFont = "Arial"
InPr.GrandezzaFont = 18
InPr.StileFont = FontStyle.Bold
InPr.Colore = Brushes.Red
InPr.Titolo = "Ordine"

Dim InPr2 As New WindowsApplication1.Miastampa(InPr)
InPr2.CaricaStampa()

Cosa ne dici?


Jeremi,

Innanzitutto grazie per la risposta. Purtroppo non sono spesso libero di dedicarmi a Vb.net come vorrei e quindi talvolta passa un po' di tempo per la risposta. Le tue indicazioni mi sono state utilissime. Tieni presente che dopo aver fatto e rifatto un paio di programmi cercando di migliorare ogni volta la leggibilita`, snellire la stesura e correggere qualche errore ho pensato che potevo creare una mia libreria di classi riutilizzabile eventualmente per altri programmi o per migliorare quanto gia` fatto. Per la materia costruttori e` del tutto nuova e non e` facile trovare informazioni in rete. Debbo dire che le tue risposte sono state sempre semplici e precise: diversamente non avrei potuto creare una serie di classi funzionanti da me gia` verificate e che mi piacerebbe magari condividere con chiunque possa essere interessato. Lavorare sulle classi rimane molto diverso da elaborare Sub Routine e Function in Windows.Form

---------------------------------------------------------------------------
Ho copiato quanto mi hai indicato con una piccola differenza ma ho questo errore:
Errore 1 '_instit' non può esporre il tipo 'InsTitolo' all'esterno del progetto mediante class 'Miastampa'. G:\Documents and Settings\Antonio\Desktop\MiaStampa.vb 10 37 ProvaClasseStampa
---------------------------------------------------------------------------
Ti mostro cosa ho aggiunto:

Private InsTit
Public Sub New(ByVal _instit As InsTitolo)
InsTit = _instit
End Sub

Ho tolto:

Dim inSTit As New WindowsApplication1.InsTitolo




ans66 Profilo | Junior Member

Jeremy,

Se puoi vorrei avere un'altra delucidazione: come faccio a rendere visibile una Function come ScriviCorpoPagina (vedi sotto) solo alla classe MiaStampa e non a tutto il resto. Se indico Public Function ScriviCorpoPagina posso richiamarla con:

Dim InsCor As New Corpo
Dim MaxRighe As Integer = InsCorpo.ScriviCorpoPagina(e, PosY)

dalla Classe MiaStampa o da qualsiasi altra classe (e non e` quello che voglio). Se indico Private Function ScriviCorpoPagina non e` piu' visibile a nessuna altra classe. Ho provato a vedere se riuscivo a creare un costruttore ma non ci sono riuscito.

Grazie ancora

----------------------------------------------------------------------------
Class CorpoStampa

Public TipoFont As String
Public GrandezzaFont As Integer
Public StileFont As System.Drawing.FontStyle
?????? Function ScriviCorpoPagina(ByVal eV As System.Drawing.Printing.PrintPageEventArgs, _
ByVal AltezzaPartenza As Integer) As Integer

Dim Fnt As New Font(TipoFont, GrandezzaFont, FontStyle.Regular)
Dim AltFnt As Integer = Fnt.Height
Return (eV.MarginBounds.Height - AltezzaPartenza) / AltFnt

End Function



End Class

Jeremy Profilo | Guru

Ciao Ans.
prova con Protected!!
In questo modo avrai, il metodo dichiarato Protected, con visibilità a livello di Classe e di tutti i suoi derivati ..... ma non potrai accederci da una classe esterna pur che sia nello stesso assembly.
Per maggiori informazioni dai un occhio a questo link:
http://msdn.microsoft.com/it-it/library/8050kawf(VS.80).aspx

Facci sapere..
Ciao

ans66 Profilo | Junior Member

Jeremy,

Ho deciso di portare le Function dentro Class Miastampa e lasciare le variabile in Class Corpo. Cosi' funziona e posso lasciare le funzioni Private e quindi non visibili

Grazie
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-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5