Resize Form czyli WinForms-y okiem laika
W WinFormsach programuje zupełnie sporadycznie. Wole warstwy domenowe, serwisowe, bazodanowe i prezentacyjne (w modelach MVP). Widoki toleruje tylko pod MonoRail i ASP.NET. Ale WinForms ? .... e to nie dla mnie. Niestety życie bywa brutalne. W moim aktualnym projekcie integruje system finansowo księgowy z danymi dostarczanymi z działu aktuarialnego. Procesem przetwarzania danych kieruje aplikacja WinForms-owa. Prosty wygląd w postaci zakładek, gdzie dwie zakładki posiadają kontrolki na wprowadzenie parametrów. Natomiast jedna posiada textbox z zawartością logu, a jeszcze inna ReportViewer z Microsoft Reporting.

Poprzedni programista, który projektował UI, nie uwzględnił tego aby Form był w pełni resizable a wraz z nim textbox z zawartością logu oraz ReportViewer. Mimo, że program potrafi wykonywać skomplikowane przeliczenia księgowe wg. zawiłych reguł biznesowych, łącznie z importem do systemu to brak ładnego powiększania okienka może spowodować że projekt zostanie odrzucony. Dla klienta ważniejsze jest to co widzi aniżeli to co siedzi w środku. To normalne. Lecz niestety zadanie zrobienia resizable form spadło na mnie. No to zaczynamy. www.google.com ... "form c# resize child controls" ... press "search" ... i w sumie nic ciekawego nie znalazłem. No dobra filozofia jest przecież banalna. Jak powiększę okno o powiedzmy 100 px to pozostałe kontrolki też należy powiększyć o te 100 px. Piece of cake. Hmm, ale jak to zrobić i się nie narobić i żeby na przyszłość można było w łatwy sposób dokładać następne kontrolki, które mają reagować tak samo na powiększenie okna.
Na początek należy przechować jaka jest różnica w wysokości i szerokości pomiędzy kontrolkami a oknem. Początkowo do przechowania WidthDifference i HeightDifference zrobiłem własną strukturę, ale szybko okazało się ze już jest taka struktura - Size, wiec postanowiłem ją wykorzystać. Końcowe rozwiązanie mojego problemu jest następujące.
Deklarujemy pole ...
private IDictionary<Control, Size> _sizeDifferences = new Dictionary<Control, Size>();
... podczas ładowania okna zapamiętujemy różnice taką metodą ...
private void RememberInitialSizeDifferences()
{
_sizeDifferences.Add(MainTabControl, this.Size - MainTabControl.Size);
_sizeDifferences.Add(CurrentLogTextBox, this.Size - CurrentLogTextBox.Size);
_sizeDifferences.Add(ImportSummaryReportViewer, this.Size - ImportSummaryReportViewer.Size);
}
... dodajemy metodę do eventu Resize dla obiektu Form z taką zawartością ...
private void MainWindows_Resize(object sender, EventArgs e)
{
foreach (var pair in _sizeDifferences)
pair.Key.Size = this.Size - pair.Value;
}
Szybko, prosto i przyjemnie. Można się jeszcze pokusić o bardziej uniwersalne rozwiązanie i aby jakism fajnym atrybutem dekorować te kontrolki, które mają się powiększać wraz z oknem o tę sama ilośc pikseli co samo okno. Ale ... WinFormsy to nie moja działka.