2015-12-01 20 views
6

Ho progettato una finestra di dialogo Windows Form che dovrebbe essere riutilizzabile in altre applicazioni, WPF e Windows Form. Funziona perfettamente quando lo uso in un'applicazione Windows Form, ma causa problemi di layout quando viene chiamato in un'applicazione WPF. Le dimensioni e le dimensioni sono incoerenti se misurate dai pixel sullo schermo, da quello che dice l'API WinForms e da Spy ++. La finestra è di 10 pixel più larga e più alta quando viene eseguita senza un debugger di quanto Spy ++ afferma di essere, e di quanto dirlo dovrebbe essere. Qual è il problema qui? Non riesco a trovare nulla, ma dire che è un .NET Framework gravemente rotto.La finestra di dialogo non ha richiesto ulteriore spazio

Ecco il codice classe Form:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace DialogTestApp 
{ 
    internal class MyDialog : Form 
    { 
     public MyDialog() 
     { 
      Text = "Title"; 
      Width = 500; // -> actually 510 (Spy++ says 500) 
      Height = 300; // -> actually 310 (Spy++ says 300) 
      Font = SystemFonts.MessageBoxFont; 
      FormBorderStyle = FormBorderStyle.FixedDialog; 
      MaximizeBox = false; 
      MinimizeBox = false; 
      ShowInTaskbar = false; 
      StartPosition = FormStartPosition.CenterScreen; 

      TableLayoutPanel mainLayout = new TableLayoutPanel(); 
      mainLayout.BackColor = Color.FromArgb(255, 171, 255); // pink 
      mainLayout.Dock = DockStyle.Fill; 
      mainLayout.Margin = Padding.Empty; 
      mainLayout.Padding = Padding.Empty; 
      mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Only use minimum required space 
      mainLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100)); 
      Controls.Add(mainLayout); 

      int row = 0; 
      Label label = new Label(); 
      label.Text = "Hello world. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque suscipit vestibulum gravida."; 
      label.Font = new Font(Font.FontFamily, 12); 
      label.MaximumSize = new Size(mainLayout.Width, 0); 
      label.AutoSize = true; 
      label.Dock = DockStyle.Fill; 
      label.Margin = Padding.Empty; 
      label.BackColor = Color.FromArgb(58, 171, 58); // green 
      label.ForeColor = Color.White; 
      mainLayout.Controls.Add(label, 0, row++); 

      TextBox textBox = new TextBox(); 
      textBox.Dock = DockStyle.Fill; 
      textBox.Margin = Padding.Empty; 
      textBox.Multiline = true; 
      textBox.ScrollBars = ScrollBars.Both; 
      mainLayout.Controls.Add(textBox, 0, row++); 
     } 
    } 
} 

Basta mettere questo file in un progetto di applicazione WPF vuota e lo chiamano dal costruttore dell'applicazione:

public MainWindow() 
{ 
    InitializeComponent(); 

    new MyDialog().ShowDialog(); 
    Application.Current.Shutdown(); 
} 

Ecco come si presenta con un debugger:

enter image description here

E senza:

enter image description here

Il bordo rosa supplementare è i 10 pixel che non dovrebbero essere lì. L'etichetta verde è impostata per riempire tutto lo spazio.

+0

di Windows 10 ... Nessun problema. – Spawn

+0

Il tuo ** interno ** 'classe MyDialog' non può essere istanziato in altri progetti WPF (a meno che non si tratti di un'assemblea di amici), forse stai creando un'istanza di un'altra classe? –

+0

Non sono sicuro se è il problema, ma 'label.AutoSize = true;' e 'label.DockStyle = DockStyle.Fill' sono conflitti. 'AutoSize' proverà a comprimere in' PreferredSize' quando il 'Text' o' Font' è cambiato, dove come 'DockStyle.Fill' è un suggerimento che potrebbe essere usato dal' LayoutEngine' del controllo genitore. – Loathing

risposta

2

Anche senza il TableLayoutPanel, Label e utilizzando System.Windows.Forms.Application.Run(new MyDialog()), il problema si verifica ancora. La linea che causa il problema è FormBorderStyle = FormBorderStyle.FixedDialog;

sembra essere lo stesso problema come descritto qui: Form tells wrong size on Windows 8 — how to get real size?

Soluzione:

 mainLayout.SizeChanged += delegate { 
      label.MaximumSize = new Size(mainLayout.Width, 0); 
      //MessageBox.Show("hi"); // called when not ran in debugger 
     }; 
+0

Non mi interessa molto delle dimensioni effettive della finestra. Deve essere abbastanza grande da contenere il contenuto. Sui sistemi DPI alti ci saranno comunque lievi variazioni. Questo è quello che uso per il contenitore di layout flessibile. Ma non posso accettare che i valori delle dimensioni siano incoerenti nell'area client stessa e che il layout produca valori incoerenti. E non capisco cosa cambi la presenza di un debugger. – ygoe

+0

@LonelyPixel Allora provare a rimuovere la linea 'label.MaximumSize = new Size (mainLayout.Width, 0);' La dimensione massima è calcolata in modo errato (alcuni elementi visivi problema, come ha sottolineato). – Loathing

+0

Non funziona, vedere il codice aggiornato nella domanda. – ygoe