So ziemlich alle moderneren GUI Toolkits bieten heute die Möglichkeit die einzelnen Komponenten eines Bildschirmes bei Vergrößerung oder Verkleinerung der Auflösung entsprechend anzupassen. Dies passiert jedoch meist über Distanzblöcke, Anchors, oder Grids. Dies ist zwar bei Standard GUIs meist ausreichend, stößt aber spätestens dann an die Grenzen, wenn bei einem komplexen SCADA System alle dargestellten Elemente zueinander verschobe bzw vergrößert werden müssen und die Relationen der Elemente zueinander erhalten bleiben sollen. Es sieht ja auch blöd aus, wenn bei einem Piping Diagramm auf einmal die Rohre nicht mehr aneinander stoßen sondern Lücken dazwischen sind.

Bei dem Versuch diese Probleme mit den normalen Positionierungs-Mitteln eines GUI Frameworks zu lösen wird man kläglich scheitern.

Ebenfalls gibt es das Problem, dass vielleicht die Elemente zueinander in Relation bleiben, allerdings gibt es keine Lösung, den Font entsprechend auch noch anzupassen. Was nutzt es wenn bei Wechsel von einem 640 x 480 Schirm auf Full HD zwar die Element angepasst werden, aber die Fonts in Ihrer Größe nicht mit vergrößert werden. Man wird dann zwangsläufig auf dem HD Display zur Lupe Greifen müssen. Oder besser zum Fernglas, denn meist geht mit der Erhöhung der Bilddiagonale und Auflösung auch eine Erhöhung der Distanz zwischen Betrachter und Display einher.

Hier beschreiben wir eine Klasse für Windows Forms, die dieses Problem löst.

Die Solution für VS2012 finden Sie im zip Format im Anhang zu diesem Artikel.

Zunächsten Leiten wir uns eine Klasse von UserControl ab, die wir bspw. ResizeControl nennen. Diese abgeleitete Klasse wird nun um ein paar Funktionen erweitert.

1.

Zunächst wird eine neue Struktur angelegt. Hier werden zu jedem Control das auf dem Container liegt die ursprünglichen Daten gespeichert

struct myControl

{

public string Name;      // Control Name

public Point Location;   // Control Location

public int Width;        // Control Breite

public int Height;       // Control Höhe

public float CharSize;   // Control Zeichengröße

}

2.

Es wird ein Dictionary deklariert, dass für alle Controls die zugehörigen Daten der Struktur myControl speichert.

Dictionary<string, myControl> myControls = newDictionary<string, myControl>();

3.

Für das Container Control werden dann einige original Daten gespeichert.

public float factorWidth, factorHeight;

public float OrigWidth, OrigHeight;

4.

Als erste neue Funktion wird das Speichern der vorhandenen Controls auf dem Container realisiert. Die Funktion ist rekursiv und betrachtet alle Controls, auch die, die in Sub-Controls liegen. Controls, die selber resizable sind, werden nicht berücksichtigt.

publicvoid FillControls(ControlCollection concol)
{
try
{
for (int i = 0; i < concol.Count; i++)
{
// Don’t resize children of resizable controls, because they resize themself
if (!(concol[i] isResizableControl) && concol[i].HasChildren)
{
ControlCollection newcol = concol[i].Controls;
FillControls(newcol);
}
myControl c = newmyControl();
c.Name = concol[i].Name;
c.Location = concol[i].Location;
c.Width = concol[i].Width;
c.Height = concol[i].Height;
c.CharSize = concol[i].Font.Size;

if (c.Name != „“ && !myControls.ContainsKey(c.Name))
{
myControls.Add(c.Name, c);
}
}
}
catch (Exception E)
{
Console.WriteLine(„“);
}
}

5.

Für das eigentliche resize der Controls wird nun eine Funktion erstellt die durch alle Controls geht und diese in Position und Größe anpasst. Auch rekursive für alle Sub-Controls.

publicvoid resizeControls(ControlCollection concol)
{
try
{
for (int i = 0; i < concol.Count; i++)
{
// Resize also all children of the container
// Don’t do it for resizable controls because they resize themself
if (!(concol[i] is ResizableControl) && concol[i].HasChildren)
{
ControlCollection newcol = concol[i].Controls;
resizeControls(newcol);
}

if (myControls.ContainsKey(concol[i].Name))
{
myControl mc = myControls[concol[i].Name];
concol[i].Location = new Point((int)((float)mc.Location.X * factorWidth), (int) ((float)mc.Location.Y * factorHeight));
concol[i].Width = (int)((float)mc.Width * factorWidth);
concol[i].Height = (int)((float)mc.Height * factorHeight);

float newFontSize = mc.CharSize * factorHeight;
Font myFont = new Font(concol[i].Font.FontFamily, newFontSize, concol[i].Font.Style);
concol[i].Font = myFont;
}
}
}
catch (Exception E)
{
Console.WriteLine(„“);
}
}

Schreibe einen Kommentar