Newsgroup: it.comp.lang.visual-basic
Titolo: VB .NET: Sapere la dimensione di una form da un'altra form

Ciao a tutti,
Ho una form (form1) principale e una form (form2) secondaria che contiene un
pulsante. Dal Click del pulsante vorrei sapere la .width della form1, ma in
VB.NET
 il seguente codice non funziona:
MsgBox (Form1.Width)
Questo perché il ".Width" non sembra essere una proprietà di Form1. In VB6
questo codice funziona. Come faccio a farlo funzionare un VB .NET? In
sostanza, dal contesto Form2 dovrei sapere la width della Form1.
Grazie,
Andy

 questo codice funziona.
Argomento sempre gettonato
in VB6 quando aggiungi in design una form 'Form1' il nome stesso identifica
due cose; la classe Form1 e una variabile oggetto autoistanziante di nome
Form1 e di classe Form1... per dirla terra-terra e' come se in un modulo BAS
esistesse la dichiarazione 'Public Form1 As New Form1'
In 
VB.NET
 questo non e' piu' vero, e quando disegni una nuova form il suo
nome rappresenta solo (correttamente aggiungerei) la classe; le property che
vedi associate a Form1 sono property di classe (Shared in VB, static in C)
mentre .Width e' una property di istanza e per questo non e' visibile usando
il nome di classe; per accedere devi quindi fare riferimento ad una
variabile del tipo corretto.
Per inciso, per visualizzare una form, e a maggior ragione 2 come nel tuo
esempio, devi sempre dichiarare e istanziare una variabile come sopra... se
non lo hai fatto probabilmente e' perche':
- Form1 e' l'oggetto di partenza del progetto
- Hai usato il Wizard da VB6 a 
VB.NET
 che crea automaticamente le istanze
predefinite di form, per compatibilita'
Ricapitolando: per poter fare quello che chiedi da Form2, devi fare in modo
di impostare attraverso un qualche membro pubblico (per esempio la property
Owner o una tua creata ad hoc) un riferimento all'istanza corrente di Form1
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 Owner o una tua creata ad hoc) un riferimento all'istanza corrente di
Form1
Purtroppo qui non ho capito... A cosa ti riferisci con la proprietà Owner?
Per non esserti troppo di fastidio con le mie domande, sai se esiste qualche
sito web che spiega come risolvere questo problema?
Grazie mille! :-)
Andy

 rendere globale la variabile che uso per instanziare Form1 nella Sub_Main?
[SNIP]
No, affatto, non volevo dire questo.... devi pero' fare in modo che Form2
acceda alla medesima istanza locale che hai creato nella Sub Main.
Un sistema gia' pronto, come dicevo, e' quello di sfruttare la property
Owner, per esempio:
'in un punto qualunque di Form1
Dim f2 As Form2 = New Form2
f2.Owner = Me 'l'istanza attuale di Form1
f2.Show
'oppure
Dim f2 As Form2 = New Form2
Me.AddOwnedForm(f2)
f2.Show()
'o anche, se form2 e' modale
Dim f2 As Form2 = New Form2
f2.ShowDialog(Me)
e a questo punto dal codice di Form2 fai riferimento a Owner.Width
L'unica controindicazione e' data dal fatto questo comporta anche qualche
leggero cambiamento nel comportamento della form figlia, nello specifico fa
si che tale finestra resti sempre in primo piano rispetto a quella Owner;
mentre per le finestre modal e' praticamente ininfluente, per quelle
modeless no, e potresti non volere questo effetto, in tal caso non fai altro
che definire una tua property personalizzata di tipo Form, oppure aggiungere
un overload al metodo Show:
Public Class Form2
    Inherits System.Windows.Forms.Form
    Private mCaller As Form
    Public Overloads Sub Show(ByVal Caller As Form)
        'salvi un riferimento al chiamante per usarlo in seguito
        mCaller = Caller
        MyBase.Show()
    End Sub
End Class
e da Form1 il tutto si riduce a
Dim f2 As Form2 = New Form2
f2.Show(Me)
Vedi un po' cosa preferisci...


 CUT
Grazie per le informazioni, credo di aver capito cosa intendi. Il problema è
che non riesco ad applicarlo al mio caso. In sostanza devo realizzare una
funzione in un modulo che, passato come parametro una form, la centri
rispetto alla form principale. Ecco il vecchio codice vb6:
    Sub CenterForm(MyForm As Form)
        MyForm.Move (MainFrm.Width-MyForm.Width) \ 2, (MainFrm.Height -
MyForm.Height) \ 2
    End Sub
In VB .NET non saprei proprio come fare; l'idea era:
    Sub CenterForm(ByVal MyForm As Form)
        MyForm.Location = New Point((MainFrm.Size.Width-MyForm.Size.Width) \
2, (MainFrm.Size.Height - MyForm.Size.Height) \ 2)
    End Sub
Ma ovviamente non funziona... Qui non posso usare il tuo metodo Owner, o no?
Grazie ancora!
Andy
PS. So' che esiste una proprietà in VB .NET che fa proprio questo (centrare
una form), ma non posso usarla perché in alcune mie form la loro dimensione
può cambiare durante l'evento Load, sballando la proprietà built-in di
"centratura"...

 Ma ovviamente non funziona... Qui non posso usare il tuo metodo Owner, o
no?
Certamente si... quanto detto finora era valido per codice scritto
all'interno di Form2 (MyForm nella tua funzione), ma essendo Owner una
property pubblica e' utilizzabile anche per codice esterno:
Sub CenterForm(ByVal MyForm As Form)
    With MyForm
        .Location = New Point((.Owner.Size.Width - .Owner.Size.Width) \ 2 _
        , .Owner.Size.Height - .Size.Height) \ 2)
    End With
End Sub
Piu' in generale vale il concetto espresso all'inizio: non esiste un istanza
predefinita di MainFrm, devi quindi trovare il modo di passare quella
corretta alla tua routine... il discorso dell'Owner e' utile per codice
interno alle form figlie, che sembrava essere il tuo caso nel primo
messaggio; per una routine globale come questa puoi anche farne a meno e
aggiungere banalmente un secondo parametro. La scelta di un sistema o
l'altro e' tutta in funzione di come e dove mantieni l'istanza di MainFrm
Ciao


 l'altro e' tutta in funzione di come e dove mantieni l'istanza di MainFrm
L'istanza di MainFrm non la mantengo, la instanzio (come Dim) in Sub_Main e
finisce lì. Comunque ho provato a creare una nuova Function pubblica nella
classe MainFrm (in modo da restituire all'esterno la dimensione corrente
della form), ma non funziona se chiamo MainFrm.MiaFunction; immagino che
devo istanziarla...
E se invece facessi:
Sub CenterForm(ByVal MyForm As Form)
    Dim newMainFrm as New MainFrm
    With MyForm
        .Location = New Point((newMainFrm.Size.Width - .Size.Width) \ 2 _
        , newMainFrm.Size.Height - .Size.Height) \ 2)
    End With
End Sub
Dici che funziona? Ho un calo di prestazioni ad instanziare newMainFrm ogni
volta che chiamo CenterForm (Me) nell'evento Load di tutte le form
dell'applicsativo?
Grazie!
Andy

 Dici che funziona?
NOTA MIA: Mi sono accorto adesso che non funziona, o meglio, funziona, ma
ogni volta mi crea un'istanza di default quindi se l'utente ha spostato la
"vera" MainFrm rimango fritto.
Ho visto comunque che il tuo suggerimento dell'Owner funziona senza
problemi; il "problema" è che non so' se avrò sempre form Modali e mi hai
detto che c'è un problema con form Modeless (non è detto che le voglia
sempre in primo piano...). Esistono altre alternative?
Ho controllato adesso: nel Sub_Main non salvo l'istanza di MainFrm in una
variabile, ma passo direttamente "New MainFrm" a .Run
Grazie,
Andy

 dell'applicsativo?
Il calo di prestazioni puo' anche essere trascurabile; il punto e' che stai
creando una nuova istanza, quindi le dimensioni sono quelle che hai dato *in
design* e non necessariamente sono quelle effettive dell'istanza di MainFrm
attiva al momento della chiamata.
Insomma, come si dice dalla mie parti, "musse, non c'e' n'e'": devi
mantenere un riferimento all'istanza che crei in Sub Main; se non la vuoi
avere globale, la devi impostare a tutte le form figlie (mantenendo di fatto
in vita quella locale), se non vuoi/puoi usare l'Owner, devi definire una
tua property/metodo in ogni figlia.
Di tutto quello che si e' visto probabilmente la soluzione migliore e'
quella di definire un metodo Show personalizzato (seconda risposta) che a
questo punto puoi integrare direttamente con il tuo codice di centratura


 form, la centri rispetto alla form principale.
a parte tutti i consigli di Luca, in .net c'č una apposita proprietą della
form, che ti permette di definirne la posizione in fase di apertura, che puņ
essere la posizione standard, o centrata sullo schermo, o centrata sulla
finestra "padre".
hth
--
Salutoni
Sergio

 finestra "padre".
Grazie per la risposta, questo lo so', ma non posso usarla (vedi il PS nel
messaggio precedente).
Andy

 PS nel messaggio precedente).
sorry. non ho letto fino in fondo.
--
Salutoni
Sergio