Ovládací prvek CalendarView v UWP nám umožňuje v aplikaci zobrazit kalendář s mnoha funkcemi možnostmi přizpůsobení. Jak ale můžeme upravit vzhled jednotlivých dnů v měsíci? Na to se podíváme v tomto článku.
Problém
Ve výchozím stavu CalendarView zobrazuje čísla dnů v měsíci horizontálně a vertikálně vycentrované:

Přestože vypadá tento formát dobře, možná preferujete jiné rozložení. Například zabudovaná aplikace Outlook Kalendář používá pro čísla zarovnání nahoru doleva:

Kde jsou moje čísla dnů?
První rychlý nápad každého vývojáře v XAMLu je, že by mělo být možné upravit výchozí styl CalendarView. Bohužel k našemu překvapení ve stylu není o číslech dnů žádná zmínka. Druhým nápadem je samozřejmě modifikovat style CalendarViewDayItemStyle. Ač se zdá, že by to mělo vést k úspěšnému výsledku, znovu narážíme na překážku. Každá změna v tomto Stylu ovliňuje oblast za číslem dne, ale ne číslo samotné. Co se děje? Odpověď má pro nás XAML Live Visual Tree explorer.

Prvním synem CalendarViewDayItem je obsah který vytvoříme v CalendarViewDayItem.Template kdežto druhý syn je TextBlock, který zobrazuje číslo dne. Tento TextBlock je přidán ovládacím prvkem CalendarView. Jak se k němu dostaneme?
Už zase to měníte?
Protože se data CalendarView často mění, neexistuje žádná vlastnost typu Items, přes kterou bychom mohli získat přístup přímo k jednotlivým dnům. Namísto toho je tu událost CalendarViewDayItemChanging , která je volána pokaždé, když je buď vytvořen nebo modifikován CalendarViewDayItem. Uvnitř kompaktně pojmenované třídy CalendarViewDayItemChangingEventArgs najdeme vlastnost Item přes kterou na náš CalendarViewDayItem můžeme přistoupit a najít pak uvnitř náš TextBlock. Nejprve si vytvoříme pomocnou metodu pomocí VisualTreeHelper, která najde prvního přímého potomka DependencyObject daného typu:
private T FindFirstChildOfType<T>(DependencyObject control) where T : DependencyObject { var childrenCount = VisualTreeHelper.GetChildrenCount(control); for (int childIndex = 0; childIndex < childrenCount; childIndex++) { var child = VisualTreeHelper.GetChild(control, childIndex); if (child is T typedChild) { return typedChild; } } return null; }
Nyní zbývá už jen jediné - najít a upravit dlouho hledaný TextBlock ku obrazu svému:
private void CalendarView_OnCalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChanging args) { var textBlock = FindFirstChildOfType<TextBlock>(args.Item); if (textBlock != null) { textBlock.HorizontalAlignment = HorizontalAlignment.Left; textBlock.VerticalAlignment = VerticalAlignment.Top; textBlock.Margin = new Thickness(12); textBlock.FontSize = 26; textBlock.FontWeight = FontWeights.Light; } }
Et voilà - náš CalendarView je nyní plně personalizovaný:

Zdrojový kód
Ukázkový zdrojový kód k tomuto článku můžete najít na mém GitHubu.
Shrnutí
Ukázali jsme sie, jak přistupovat k jednotlivým dnům v CalendarView a jak přizpůsobit vzhled čísel dnů v měsíci pomocí CalendarViewDayItem uvnitř události CalendaryViewDayItemChanging.