2010-12-13 8 views
8

Fondamentalmente sto riscontrando due problemi con MDI C# .NET. È possibile scaricare la soluzione VS2010 che riproduce bug here.C# .NET Bug MDI quando si nasconde e mostra di nuovo un modulo figlio massimizzato e quando ingrandita, l'icona del modulo figlio non può essere modificata

1) Quando si nasconde e mostra di nuovo una forma di bambino massimizzata, non viene ingrandita correttamente correttamente e non diventa né ingrandita né in stato normale.

childForm = new Form(); 
childForm.Text = "Child Form"; 
childForm.MdiParent = this; 

... 

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = true; 
} 

... 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = false; 
} 

Quando form figlio è ingrandita, quindi programicaly nascosti e mostrati ancora una volta, diventa qualcosa di simile (si prega di notare la barra dei menu - appare scatola di controllo del form figlio, ma form figlio non è ingrandita):

alt text

In questa fase, la forma del bambino non può essere spostata. Tuttavia, ho trovato una soluzione per questo, semplicemente mostrando e nascondendo un modulo figlio fittizio, che costringe il vero modulo figlio a diventare correttamente massimizzato. Ma questo rende l'area MDI sfarfallio. Provati metodi Invalidate, Refresh, Update, ma non aiutano. Forse ci sono altri metodi per ovviare a questo errore e non creare uno sfarfallio dell'area MDI con un modulo figlio fittizio?

private void workaround1Button_Click(object sender, EventArgs e) 
{ 
    dummyForm.Visible = true; 
    dummyForm.Visible = false; 
} 

2) Quando la forma figlio è ingrandita, l'icona del modulo figlio viene visualizzata sulla barra dei menu. Tuttavia, se è necessario modificare l'icona mentre il modulo figlio è ingrandito, l'icona sulla barra dei menu non viene aggiornata (vedere l'immagine sopra). Ho trovato una soluzione anche per questo, che fondamentalmente nasconde e mostra la barra dei menu. L'icona viene aggiornata, ma rende tutto sfocato sotto la barra dei menu. Provati metodi Invalidate, Refresh, Update, ma non aiutano. C'è un altro modo per rendere la barra dei menu per aggiornare l'icona del modulo figlio?

private void workaround2Button_Click(object sender, EventArgs e) 
{ 
    menuStrip.Visible = false; 
    menuStrip.Visible = true; 
} 

Inoltre ho notato che quando form padre è in modalità finestra di stato normale (non ingrandita) e si modifica la larghezza o l'altezza del modulo di 1 pixel, form figlio viene massimizzata come dovrebbe essere e l'icona del modulo figlio sulla barra dei menu viene aggiornata correttamente e non hai bisogno di altre soluzioni alternative che ho descritto sopra. Se modifico la dimensione del modulo in modo programmatico, il form sfarfallio di 1 pixel e non posso farlo quando la forma genitoriale è ingrandita. C'è un modo come potrei invocare la funzionalità di ridisegno/aggiornamento che viene chiamata quando ridimensionate un modulo e che rende la forma del bambino ingrandita correttamente e l'icona sulla barra del menu aggiornata?

risposta

1

Trovato un modo per aggirare questi bug.

Prima di tutto è necessario sospendere la pittura di un modulo e dei relativi figli. Ho trovato un thread molto utile here, che descrive come farlo.

Dopo aver sospeso la verniciatura, è necessario chiamare il metodo UpdateBounds del controllo e aumentare ClientRectangle Width o Height di uno e quindi ridurlo allo stesso valore precedente. Ciò richiama la funzionalità di layout che rende tutto da aggiornare/ridipingere. L'ultimo passo è abilitare la pittura. Immagino che non sia una soluzione molto bella, ma funziona.

StopDrawing(); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1); 
StartDrawing(); 

trovo che sospende la pittura molto utile non solo per lavorare intorno a questi due insetti, ma anche, in generale, per rendere il lavoro GUI più agevolmente. Immagino che questo possa aiutare a rimuovere ogni tipo di sfarfallio. Tuttavia, questa soluzione richiede P/Invokes, che dovrebbe essere evitato in generale.

1

Sei stanco di usare Nascondi/Mostra invece di impostare la visualizzazione su vero/falso?

Prova:

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Show(); 
} 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Hide(); 
} 
+0

Sì, ho provato, ma non cambia nulla. Penso che childForm.Visible = true/false chiami quei metodi. – Povilas

+1

In realtà dovrebbe essere il contrario. Hide/Show dovrebbe quindi essere visibile a false/true. –

1

C'è un bug nell'implementazione della classe MdiControlStrip interno, il controllo che visualizza l'icona e le Min/Max/ripristino glifi nella finestra padre. Non l'ho ancora caratterizzato, il codice non è così facile. Un classico effetto collaterale dell'insetto è che i glifi vengono raddoppiati, hai trovato alcuni altri effetti collaterali. Tuttavia, la correzione è semplice, ritardare la creazione delle finestre secondarie fino a quando non viene completato il costruttore. In questo modo:

public MainForm() 
    { 
     InitializeComponent(); 
    } 
    protected override void OnLoad(EventArgs e) { 
     childForm = new Form(); 
     childForm.Text = "Child Form"; 
     childForm.MdiParent = this; 

     dummyForm = new Form(); 
     dummyForm.MdiParent = this; 
     dummyForm.WindowState = FormWindowState.Maximized; 
     base.OnLoad(e); 
    } 
+0

Ah, sì, hai usato l'evento Load. Sposta base.OnLoad() verso il basso. Funziona sulla mia macchina ™. –

+0

Provato la tua correzione sostituendo il metodo OnLoad, ma rimane lo stesso comportamento bug. Niente cambia. E le forme figlio devono essere create dinamicamente, quindi questa non sarebbe davvero una soluzione per me. – Povilas

1

Che ne dici di questa soluzione alternativa?

UPDATE

ho appena dato l'idea di come si possa fare. Una soluzione migliore utilizzando la stessa idea di cui sopra sarebbe un nuovo modulo di base che salva lo stato di Windows. Vedi sotto. Ricava i moduli da FixedForm anziché da Form:

public partial class FixedForm : Form 
{ 
    private FormWindowState lastWindowState; 

    public FixedForm() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnVisibleChanged(EventArgs e) 
    { 
     base.OnVisibleChanged(e); 

     if (Visible) 
     { 
      WindowState = lastWindowState; 
     } 
     else 
     { 
      lastWindowState = WindowState; 
      WindowState = FormWindowState.Normal; 
     } 
    } 
} 
+0

Sicuramente questa è una delle possibilità su come superare il bug, ma fa ingrandire l'animazione del modulo figlio per apparire più e più volte, è piuttosto fastidioso. La mia soluzione è più veloce. – Povilas

+0

Controllare il mio aggiornamento per una soluzione senza sfarfallio – Scoregraphic

+0

bene, è possibile inviare un messaggio 'WM_SIZE' all'handle della finestra principale se questo risolve il problema. – Scoregraphic

0

Perché non basta reimpostare manualmente l'icona di cui ai punti MenuStrip, dopo la creazione della finestra:

menuStripMain.Items[0].Image = null; 
Problemi correlati