Ridimensionamento automatico in Windows Form

Con il ridimensionamento automatico, un form e i relativi controlli, progettati su un computer con una determinata risoluzione dello schermo o tipo di carattere del sistema, possono essere visualizzati correttamente su un altro computer con una risoluzione dello schermo o tipo di carattere del sistema diverso. Questa funzionalità assicura che il form e i controlli vengano ridimensionati in modo coerente con le finestre native e le altre applicazioni presenti sia sui computer degli utenti che su quelli di altri sviluppatori. Il supporto di .NET Framework per il ridimensionamento automatico e gli stili di visualizzazione consente alle applicazioni .NET Framework di mantenere un aspetto coerente rispetto alle applicazioni Windows native nel computer di ogni utente.

Per la maggior parte, il ridimensionamento automatico funziona come previsto in .NET Framework versione 2.0 e successive. Le modifiche delle combinazioni tipi di carattere tuttavia possono essere problematiche. Per un esempio di come risolvere questo problema, vedere Procedura: Rispondere alle modifiche dello schema dei tipi di carattere in un'applicazione Windows Form.

Necessità di ridimensionamento automatico

Senza ridimensionamento automatico, un'applicazione progettata per un'unica risoluzione dello schermo o tipo di carattere apparirà troppo piccola o troppo grande quando si modifica tale risoluzione o tipo di carattere. Ad esempio, se l'applicazione viene progettata con Tahoma a 9 punti come base, senza regolazione apparirà troppo piccola se eseguita su un computer in cui il tipo di carattere del sistema è Tahoma a 12 punti. Gli elementi di testo, ad esempio titoli, menu, contenuti delle caselle di testo e così via, verranno visualizzati più in piccolo che nelle altre applicazioni. Inoltre, le dimensioni degli elementi dell'interfaccia utente contenenti testo, ad esempio la barra del titolo, i menu e molti controlli, dipendono dal tipo di carattere usato. In questo esempio, tali elementi appariranno anche relativamente più piccoli.

Una situazione analoga si verifica quando un'applicazione è progettata per una determinata risoluzione dello schermo. La risoluzione dello schermo più comune è di 96 punti per pollice (DPI), che è uguale al 100% di ridimensionamento dello schermo, ma una risoluzione superiore visualizza il supporto del 125%, 150%, 200% (che rispettivamente è uguale a 120, 144 e 192 DPI) e versioni successive stanno diventando più comuni. Senza regolazione, un'applicazione, soprattutto una con molti elementi grafici, progettata per un'unica risoluzione apparirà troppo grande o troppo piccola se eseguita con un'altra risoluzione.

Il ridimensionamento automatico cerca di risolvere questi problemi ridimensionando automaticamente il form e i controlli figlio in base alle dimensioni del carattere o risoluzione dello schermo relativa. Per supportare il ridimensionamento automatico delle finestre di dialogo, il sistema operativo Windows usa un'unità di misura relativa, chiamata DLU. Una DLU si basa sul tipo di carattere del sistema e la relazione con i pixel può essere determinata attraverso la funzione GetDialogBaseUnits di Win32 SDK. Quando un utente cambia il tema usato da Windows, tutte le finestre di dialogo vengono automaticamente adattate di conseguenza. .NET Framework supporta inoltre il ridimensionamento automatico in base al tipo di carattere di sistema predefinito o alla risoluzione dello schermo. Facoltativamente, il ridimensionamento automatico può essere disabilitato in un'applicazione.

Supporto originale per il ridimensionamento automatico

Le versioni 1.0 e 1.1 di .NET Framework supportavano il ridimensionamento automatico in modo semplice che dipendeva dal tipo di carattere predefinito di Windows usato per l'interfaccia utente, rappresentato dal valore win32 SDK DEFAULT_GUI_FONT. Questo tipo di carattere in genere viene modificato solo quando cambia la risoluzione dello schermo. Per implementare il ridimensionamento automatico, veniva usato il meccanismo seguente:

  1. In fase di progettazione, la proprietà AutoScaleBaseSize (ora deprecata) veniva impostata sull'altezza e sulla larghezza del tipo di carattere del sistema predefinito sul computer dello sviluppatore.

  2. In fase di esecuzione, il tipo di carattere del sistema predefinito del computer dell'utente veniva usato per inizializzare la proprietà Font della classe Form.

  3. Prima di visualizzare il form, veniva chiamato il metodo ApplyAutoScaling per ridimensionarlo. Questo metodo calcolava le dimensioni per la scalabilità relative in base a AutoScaleBaseSize e Font, quindi chiamava il metodo Scale per ridimensionare effettivamente il form e gli elementi figlio.

  4. Il valore di AutoScaleBaseSize veniva aggiornato in modo che le chiamate successive a ApplyAutoScaling non ridimensionassero progressivamente il form.

Anche se questo meccanismo era sufficiente per la maggior parte degli scopi, tuttavia aveva i seguenti limiti:

  • Poiché la AutoScaleBaseSize proprietà rappresenta le dimensioni del carattere di base come valori interi, si verificano errori di arrotondamento che si verificano quando una maschera viene ciclica attraverso più risoluzioni.

  • Il ridimensionamento automatico era implementato solo nella classe Form e non nella classe ContainerControl. Di conseguenza, i controlli utente venivano ridimensionati in modo corretto solo quando il controllo utente era progettato con la stessa risoluzione del form e veniva inserito nel form in fase di progettazione.

  • I form e i controlli figlio potevano essere progettati simultaneamente da più sviluppatori solo se le risoluzioni dei computer erano le stesse. Allo stesso modo, l'ereditarietà di un form dipendeva dalla risoluzione associata al form padre.

  • Non è compatibile con i gestori di layout più recenti introdotti con .NET Framework versione 2.0, ad esempio FlowLayoutPanel e TableLayoutPanel.

  • Il ridimensionamento non è supportato direttamente sulla risoluzione dello schermo necessaria per la compatibilità con .NET Compact Framework.

Anche se questo meccanismo viene mantenuto in .NET Framework versione 2.0 per mantenere la compatibilità con le versioni precedenti, è stato sostituito dal meccanismo di scalabilità più affidabile descritto di seguito. Di conseguenza, AutoScale, ApplyAutoScaling, AutoScaleBaseSize e alcuni overload di Scale sono contrassegnati come obsoleti.

Nota

È possibile eliminare in modo sicuro i riferimenti a questi membri quando si aggiorna il codice legacy a .NET Framework versione 2.0.

Supporto corrente per il ridimensionamento automatico

.NET Framework versione 2.0 supera le limitazioni precedenti introducendo le modifiche seguenti alla scalabilità automatica di Windows Form:

  • Il supporto di base per il ridimensionamento è stato spostato nella classe ContainerControl in modo che i form, i controlli compositi nativi e i controlli utente ricevano tutti lo stesso supporto. Sono stati aggiunti i nuovi membri AutoScaleFactor, AutoScaleDimensions, AutoScaleMode e PerformAutoScale.

  • La classe Control dispone anche di alcuni nuovi membri che le consentono di partecipare al ridimensionamento e di supportare il ridimensionamento misto nello stesso form. In particolare i membri Scale, ScaleChildren e GetScaledBounds supportano il ridimensionamento.

  • È stato aggiunto il supporto per il ridimensionamento basato sulla risoluzione dello schermo, come complemento del supporto per il tipo di carattere del sistema, definito dall'enumerazione AutoScaleMode. Questa modalità è compatibile con il ridimensionamento automatico supportato da .NET Compact Framework per facilitare la migrazione delle applicazioni.

  • È stata aggiunta all'implementazione del ridimensionamento automatico la compatibilità con i gestori di layout, ad esempio FlowLayoutPanel e TableLayoutPanel.

  • I fattori di ridimensionamento sono ora rappresentati come valori a virgola mobile, in genere con la struttura SizeF, praticamente eliminando gli errori di arrotondamento.

Attenzione

Non sono supportate combinazioni arbitrarie di DPI e modalità di ridimensionamento dei tipi di carattere. Anche se è possibile ridimensionare un controllo utente con una sola modalità (ad esempio, DPI) e inserirlo in un form con un'altra modalità (Font) senza problemi, tuttavia, se si combinano un form di base in una modalità e un form derivato in un'altra, è possibile che si verifichino risultati imprevisti.

Scalabilità automatica in azione

Windows Form usa ora la seguente logica per ridimensionare automaticamente i form e i relativi contenuti:

  1. In fase di progettazione, ogni ContainerControl registra la modalità di ridimensionamento e la risoluzione corrente rispettivamente in AutoScaleMode e AutoScaleDimensions.

  2. In fase di esecuzione, la risoluzione effettiva viene archiviata nella proprietà CurrentAutoScaleDimensions. La proprietà AutoScaleFactor calcola in modo dinamico il rapporto tra la risoluzione di ridimensionamento in fase di esecuzione e in fase di progettazione.

  3. Quando il form viene caricato, se i valori di CurrentAutoScaleDimensions e AutoScaleDimensions sono diversi, viene chiamato il metodo PerformAutoScale per ridimensionare il controllo e gli elementi figlio. Questo metodo sospende il layout e chiama il metodo Scale per eseguire il ridimensionamento effettivo. Successivamente, il valore di AutoScaleDimensions viene aggiornato per evitare il ridimensionamento progressivo.

  4. PerformAutoScale viene richiamato automaticamente anche nelle situazioni seguenti:

    • In risposta all'evento OnFontChanged se la modalità di ridimensionamento è Font.

    • Quando il layout del controllo contenitore viene ripristinato e viene rilevata una modifica nelle proprietà AutoScaleDimensions o AutoScaleMode.

    • Come accennato in precedenza, quando è in corso il ridimensionamento di un ContainerControl padre. Ogni controllo contenitore è responsabile del ridimensionamento degli elementi figlio con i propri fattori di scala e non con quello del contenitore padre.

  5. I controlli figlio possono modificare il comportamento di ridimensionamento in più modi:

    • È possibile eseguire l'override della proprietà ScaleChildren per determinare se i controlli figlio devono essere ridimensionati.

    • È possibile eseguire l'override del metodo GetScaledBounds per regolare i limiti in base a cui il controllo viene ridimensionato, ma non la logica di ridimensionamento.

    • È possibile eseguire l'override del metodo ScaleControl per cambiare la logica di ridimensionamento per il controllo corrente.

Vedi anche