This article has been localized into Czech by the community.
Ovládací prvek Calendar (kalendář)
WPF přichází s ovládacím prvkem pro zobrazení kompletního kalendáře. Je to tak jednoduché, že ho stačí umístit do vašeho okna jako je toto:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarControlSample" Height="250" Width="300">
<Grid>
<Calendar />
</Grid>
</Window>
Všimněte si, jak nyní dostanete kompletní seznam dat ve vybraném měsíci, včetně možnosti přejít na předchozí a následující měsíce pomocí šipek v horní části ovládacího prvku. Pokud nenastavíte konkrétní datum, bude zobrazen aktuální měsíc a aktuální datum bude označeno jako vybrané.
Velikost kalendáře
Pravděpodobně si všimnete z našeho prvního příkladu, že kalendář nevyužívá veškerý dostupný prostor. Ve skutečnosti, i když mu dáte velkou šířku a výšku, skutečná část kalendáře bude stále zabírat pouze tolik prostoru, kolik vidíte na snímku obrazovky, a pokud nastavíte jednu z hodnot velmi nízkou, bude kalendář viditelný pouze částečně.
Toto chování pevné velikosti není pro WPF typické tam, kde se věci obvykle rozšiřují, aby zaplnily dostupný prostor. Může to být trochu otravné, protože pokud máte pro kalendář vyhrazené určité množství prostoru, chcete, aby se tento prostor zaplnil. Naštěstí je ve WPF vše škálovatelné (s možností flexibilní změny velikosti), ale v případě ovládacího prvku Kalendář to vyžaduje trochu pomoci. Pro tento účel použijeme ovládací prvek Viewbox:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarViewboxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarViewboxSample" Height="350" Width="300">
<Viewbox>
<Calendar />
</Viewbox>
</Window>
Všimněte si, jak se ovládací prvek Kalendář nyní zvětšuje do bodu, kdy využívá veškerý dostupný prostor v šířce. Škálování se provádí na všech částech ovládacího prvku, včetně velikostí písma a šířek ohraničení.
Pravděpodobně si také všimnete, že ovládací prvek Kalendář nevyužívá veškerý dostupný prostor vertikálně. Je to patrné, protože okno je vyšší než širší a ve výchozím nastavení se Viewbox roztahuje při zachování původního poměru stran. Snadno ho můžete přimět, aby se roztáhl a zaplnil veškerý prostor v obou směrech - jednoduše změňte vlastnost Stretch z její výchozí hodnoty Uniform na Fill:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarViewboxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarViewboxSample" Height="350" Width="300">
<Viewbox Stretch="Fill" StretchDirection="UpOnly">
<Calendar />
</Viewbox>
</Window>
Nyní zabere veškerý dostupný prostor, v obou směrech. To však obecně není vhodné, protože většina ovládacích prvků, a tento konkrétně, bude vypadat podivně, pokud dostane neobvyklé rozměry, například 800 pixelů vysoké a 300 pixelů široké. Režim Stretch nastavený na Uniform (nebo vynechaný, protože je ve výchozím nastavení) je obvykle nejlepší volbou.
Doporučil bych však zahrnout vlastnost StretchDirection, jak je vidět v tomto příkladu. Umožňuje nám specifikovat, že obsah by měl být škálován pouze nahoru nebo dolů, což může být užitečné. Například ovládací prvek Kalendář se stane zcela nepoužitelným pod určitou velikostí, kde už není vidět, co to je, a aby se tomu zabránilo, můžete nastavit StretchDirection na UpOnly - ovládací prvek Kalendář pak nebude škálován pod jeho výchozí velikost.
Nastavení počátečního zobrazení data pomocí DisplayDate
Ovládací prvek Kalendář ve výchozím nastavení zobrazí aktuální měsíc, ale můžete to změnit použitím vlastnosti DisplayDate. Stačí ji nastavit na datum v měsíci, se kterým chcete začít, a odrazí se to v ovládacím prvku:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarDisplayDateSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarDisplayDateSample" Height="300" Width="300">
<Viewbox>
<Calendar DisplayDate="01.01.2014" />
</Viewbox>
</Window>
Kalendář mód výběru (SelectionMode)
Vlastnost SelectionMode je zajímavá. Změnou z její výchozí hodnoty, SingleDate, můžete vybrat více dat nebo rozsahy dat. Zde je příklad:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarSelectionModeSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarSelectionModeSample" Height="300" Width="300">
<Viewbox>
<Calendar SelectionMode="SingleRange" />
</Viewbox>
</Window>
V režimu výběru SingleRange můžete vybrat celý rozsah dat, buď podržením levého tlačítka myši a tažením z jednoho data na druhé, nebo podržením kláves Ctrl nebo Shift při klikání na několik dat, podobně jako funguje vícenásobný výběr ve všech částech Windows. Na snímku obrazovky jsem vybral celý týden, od neděle do pondělí, ale stejně snadno můžete vybrat data uprostřed týdne a rozsahy, které přesahují jediný týden.
Režim SingleRange však umožňuje vybrat pouze jeden rozsah dat, přesně jak název napovídá. To znamená, že nemůžete vybrat dvě data, která nejsou vedle sebe, a nemůžete vybrat více, než jeden rozsah. Pokud to chcete, měli byste přepnout na výběr MultipleRange:
<Calendar SelectionMode="MultipleRange" />
S touto vlastností neexistují skutečně žádné limity pro data, která můžete vybrat. V tomto případě jsem vybral všechny soboty, všechny neděle a pár všedních dní mezi nimi.
Samozřejmě, pokud nechcete možnost vybrat jedno nebo několik dat, můžete nastavit SelectionMode na None (Žádný).
Nyní se podíváme na to, jak můžeme pracovat s vybranými daty ovládacího prvku Kalendář.
Práce s vybraným datem
Vlastnost SelectedDate je vše, co potřebujete, pokud povolujete pouze jednotlivé výběry (viz výše uvedené vysvětlení režimů výběru). Umožňuje nastavit i získat aktuálně vybrané datum, jak z Code-behind, tak prostřednictvím vazby dat (data bindingu).
Zde je příklad, kde nastavíme vybrané datum na zítřek z Code-behind a pak použijeme vazbu dat (data binding) k načtení vybraného data do ovládacího prvku TextBox:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarSelectionSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarSelectionSample" Height="280" Width="220">
<StackPanel Margin="10">
<Calendar Name="cldSample" SelectionMode="MultipleRange" SelectedDate="10.10.2013" />
<Label>Selected date:</Label>
<TextBox Text="{Binding ElementName=cldSample, Path=SelectedDate, StringFormat=d, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Window>
using System;
using System.Windows;
namespace WpfTutorialSamples.Misc_controls
{
public partial class CalendarSelectionSample : Window
{
public CalendarSelectionSample()
{
InitializeComponent();
cldSample.SelectedDate = DateTime.Now.AddDays(1);
}
}
}
V Code-behind jednoduše nastavíme vlastnost SelectedDate na aktuální datum plus jeden den, což znamená zítřek. Uživatel pak může tuto volbu změnit kliknutím na ovládací prvek Kalendář a prostřednictvím vazby dat vytvořené ve vlastnosti Text ovládacího prvku TextBox se tato změna automaticky projeví.
Jako další bonus, díky kouzlu vazby dat, můžete hodnotu také změnit z TextBoxu - stačí zadat platné datum a změna se okamžitě projeví v ovládacím prvku Kalendář. Pokud zadáte špatné datum, automatická validace vazby vás upozorní na problém:
Práce s vícenásobnými výběry dat
Pokud dovolíte vybrat více než jedno datum najednou, vlastnost SelectedDate nebude příliš užitečná. Místo toho byste měli použít SelectedDates, což je kolekce aktuálně vybraných dat v ovládacím prvku Kalendář. K této vlastnosti lze přistupovat z Code-behind nebo lze použít s vazbou (bindingem), jak to děláme zde:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarSelectedDatesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarSelectedDatesSample" Height="420" Width="220">
<StackPanel Margin="10">
<Calendar Name="cldSample" SelectionMode="MultipleRange" />
<Label>Selected dates:</Label>
<ListBox ItemsSource="{Binding ElementName=cldSample, Path=SelectedDates}" MinHeight="150" />
</StackPanel>
</Window>
S takto jednoduchou vazbou jsme nyní schopni zobrazit seznam aktuálně vybraných dat.
Pokud chcete reagovat na změny dat z Code-behind, můžete se přihlásit k odběru události SelectedDatesChanged ovládacího prvku Kalendář.
Nedostupná (blackout) data
V závislosti na tom, k čemu používáte ovládací prvek Kalendář, můžete chtít určitá data zneviditelnit. To by mohlo být relevantní například v rezervační aplikaci, kde chcete zabránit tomu, aby byla vybrána již rezervovaná data. Ovládací prvek Kalendář toto podporuje přímo prostřednictvím kolekce BlackoutDates, kterou můžete samozřejmě použít jak z XAML, tak z Code-behind:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarBlockedoutDatesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarBlockedoutDatesSample" Height="300" Width="300">
<Viewbox>
<Calendar Name="cldSample" SelectionMode="MultipleRange">
<Calendar.BlackoutDates>
<CalendarDateRange Start="10.13.2013" End="10.19.2013" />
<CalendarDateRange Start="10.27.2013" End="10.31.2013" />
</Calendar.BlackoutDates>
</Calendar>
</Viewbox>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfTutorialSamples.Misc_controls
{
public partial class CalendarBlockedoutDatesSample : Window
{
public CalendarBlockedoutDatesSample()
{
InitializeComponent();
cldSample.BlackoutDates.AddDatesInPast();
cldSample.BlackoutDates.Add(new CalendarDateRange(DateTime.Today, DateTime.Today.AddDays(1)));
}
}
}
V tomto příkladu ukazuji oba způsoby, jak přidat nedostupná data - prostřednictvím XAML a prostřednictvím Code-behind. Oba způsoby fungují tak, že přidáváte instance CalendarDateRange do kolekce BlackedoutDates.
V XAML zapisuji rozsahy dat pevně (většinou jen ukazuji, že to lze udělat i takto), zatímco v Code-behind dělám něco trochu chytřejšího, když nejprve přidám všechna minulá data do kolekce, jediným voláním metody AddDatesInPast() a poté přidám rozsah skládající se z dneška a zítřka.
DisplayMode - zobrazení měsíců nebo let
Vlastnost DisplayMode může změnit ovládací prvek Kalendář z místa, kde můžete vybrat datum, na místo, kde můžete vybrat měsíc nebo dokonce rok. To se dělá prostřednictvím vlastnosti DisplayMode, která má ve výchozím nastavení hodnotu Měsíc, kterou jsme použili ve všech předchozích příkladech. Zde je, jak to vypadá, když to změníme:
<Window x:Class="WpfTutorialSamples.Misc_controls.CalendarDisplayModeSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CalendarDisplayModeSample" Height="300" Width="300">
<Viewbox>
<Calendar DisplayMode="Year" />
</Viewbox>
</Window>
Nastavením DisplayMode na Year (rok) nyní můžeme vybrat měsíc daného roku. Rok můžete změnit nahoře pomocí šipek.
Ovládací prvek Kalendář také umožňuje vybrat celý rok pomocí hodnoty Decade (dekáda) pro vlastnost DisplayMode:
<Calendar DisplayMode="Decade" />
Shrnutí
Jak vidíte, ovládací prvek Kalendář je velmi univerzální prvek s mnoha možnostmi a funkcemi, který vyžaduje jen minimální konfiguraci pro použití. Pokud budujete aplikaci s jakoukoliv funkcí související s datem, pravděpodobně budete ovládací prvek Kalendář používat tak či onak.