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
.