TOC

This article has been localized into Polish by the community.

Różne kontrolki:

Kontrolka Kalendarz

WPF posiada standardowo w swoim zestawie kontrolkę do prezentacji pełnego kalendarza. Możesz umieścić taką kontrolkę w swoim oknie w bardzo prosty sposób:

<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>

Zwróć uwagę, w jaki sposób otrzymujesz dostęp do pełnej daty w ramach wybranego miesiąca, włączając w to możliwość przejścia do poprzedniego i kolejnego miesiąca z wykorzystaniem strzałek na górze kontrolki. Jeśli nie wybierzesz innej daty domyślnie zostanie ustawiona dzisiejsza data

Rozmiar kontrolki Kalendarz

Jak zapewne zauważyłeś na naszym pierwszym przykładzie Kalendarz nie zajmuje całego dostępnego miejsca w oknie. Nawet jeśli ustawić mu dużo większą szerokość i wysokość i tak kontrolka zajmie tyle miejsca ile widzimy na zrzucie ekranu w przykładzie. Natomiast jeśli zmniejszysz te wymiary, kontrolka będzie widoczna tylko w części.

Stały rozmiar nie jest zbyt typowy w WPF, gdzie wszystko zwykle próbuje wypełnić całą dostępną przestrzeń. Może to być nieco irytujące, jeśli musisz przeznaczyć wyznaczony obszar na kontrolkę. Na szczęście w WPF wszystko można skalować, jednak w przypadku kontrolki Kalendarz wymaga to pewnego wsparcia. W tym celu użyjemy kontrolki 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>

Zauważ, jak teraz kontrolka Kalendarz jest skalowana, aby zająć całą dostępną przestrzeń na szerokość. Skalowanie obejmuje wszystkie elementy kontrolki, włączając w to wielkość czcionki i szerokość obramowania.

Zapewne również zauważyłeś, że kontrolka nie zajęła całej dostępnej przestrzeni na wysokość. Widać, że okno ma większą wysokość niż szerokość i domyślnie Viewbox jest rozciągane z zachowaniem oryginalnego współczynnika proporcji. W łatwy sposób możesz to zmienić, aby kontrolka była rozciągana we wszystkich kierunkach - wystarczy zmienić właściwość Stretch z jej domyślnej wartości Uniform na wartość 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>

Teraz kontrolka wypełnia całą dostępną przestrzeń w obu kierunkach. Zasadniczo nie jest to jednak korzystne, ponieważ większość kontrolek, a zwłaszcza ta, będzie wyglądać dziwnie, jeśli będzie mieć ustawione niestandardowe wymiary, np. wysokość 800 pikseli i szerokość 300 pikseli. Ustawienie właściwości Stretch na Uniform (albo pozostawienie jej domyślnej wartości) jest zwykle najlepszym rozwiązaniem.

Polecam tutaj użycie innej właściwości: StretchDirection, tak jak w naszym przykładzie. To powoduje, że zawartość Viewbox będzie skalowana tylko w pionie, co jest bardzo użyteczne. Na przykład, kontrolka Kalendarz jest całkiem bezużyteczna, jeśli nie jest w całości widoczna. Aby tego uniknąć wystarczy ustawić parametr StretchDirection na UpOnly - wtedy Kalendarz nigdy nie będzie skalowany poniżej swojego domyślnego rozmiaru.

Inicjalne ustawienie daty z wykorzystaniem DisplayDate

Domyślnie kontrolka Kalendarz domyślnie ustawia się na bieżący miesiąc, ale możesz to zmienić z wykorzystaniem właściwości DisplayDate. Po prostu ustaw tą właściwość na datę, z którą inicjalnie kontrolka Kalendarz wystartuje:

<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>

Kalendarz - tryb wyboru zakresu dat

Właściwość SelectionMode jest interesująca. Zmieniając jej domyślną wartość (SingleDate) możesz wybrać kilka dat jednocześnie lub zakres dat. Oto przykład:

<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>

Przy ustawieniu SelectionMode na SingleRange możesz zaznaczać cały zakres dat, zarówno przytrzymując lewy przycisk myszy i przeciągając z jednej daty do drugiej lub przytrzymując klawisze Ctrl lub Shift podczas klikania różnych dat, analogicznie jak to działa w systemie Windows. Na zrzucie ekranu zaznaczyłem cały tydzień od Niedzieli do Soboty, ale można zaznaczyć zakres w środku tygodnia lub zakres, który wykracza poza pojedynczy tydzień.

Tryb SingleRange pozwala na zaznaczanie tylko pojedynczych zakresów dat, zgodnie z tym co sugeruje nazwa. Oznacza to, że nie możesz wybrać dwóch dat, które nie występują jedna po drugiej i nie możesz zaznaczyć dwóch zakresów. Jeśli byłoby ci to potrzebne, ustaw wartość parametru na MultipleRange:

<Calendar SelectionMode="MultipleRange" />

Z takim ustawieniem nie ma właściwie ograniczeń z zakresami dat, które możesz wybrać. W poniższym przykładzie zaznaczyłem wszystkie Soboty, Niedziele i kilka dni w środku tygodnia.

Oczywiście, jeśli nie chcesz pozwolić na zaznaczanie jednej lub kilku dat, możesz ustawić parametr SelectionMode na None.

Zastanówmy się teraz, jak obsłużyć wybrane zakresy dat w kontrolce Kalendarz.

Obsługa wybranej daty

Parametr SelectedDate jest wszystkim co potrzebujesz, jeśli chcesz pozwolić na zaznaczanie pojedynczej daty (zobacz powyższe wyjaśnienia dotyczące trybów zaznaczania dat). Pozwala to ci na ustawienie i pobranie aktualnie wybranej daty zarówno z kodu C#, jak i poprzez wiązanie danych.

Oto przykład, w którym ustawiamy w kontrolce datę na dzień jutrzejszy z poziomu kodu, a następnie prezentujemy wybraną datę w kontrolce TextBox poprzez wiązanie danych:

<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);
}
    }
}

W kodzie C# po prostu ustawiamy właściwość SelectedDate na bieżącą datę plus jeden dzień, co oznacza dzień jutrzejszy. Użytkownik może następnie zmienić wybraną datę klikając ją w kontrolce Kalendarz, a poprzez wiązanie danych, które jest ustawione we właściwości Text kontrolki TextBox - ta zmiana zostanie tu automatycznie odzwierciedlona.

Jako dodatkowy bonus, dzięki magicznemu wiązaniu danych, możesz także zmienić datę w kontrolce TextBox - po wpisaniu poprawnej daty zmiana będzie od razu widoczna w kontrolce Kalendarz. Po wpisaniu błędnej daty, automatyczna walidacja danych od razu cię o tym poinformuje:

Obsługa wyboru wielu zakresów dat

Jeśli pozwolisz na wybór wielu zakresów dat, właściwość SelectedDate nie będzie już dla ciebie taka przydatna. Zamiast tego powinieneś użyć właściwości SelectedDates, która jest kolekcją wybranych aktualnie dat w kontrolce Kalendarz. Masz dostęp do tej właściwości z poziomu kodu, albo możesz ją użyć przy wiązaniu danych, tak jak na poniższym przykładzie:

<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>

Z tym prostym wiązaniem jesteśmy w stanie pokazać listę aktualnie wybranych dat.

Jeśli chciałbyś obsłużyć zmianę wyboru dat w kontrolce z poziomu kodu, możesz podłączyć się do zdarzenia SelectedDatesChanged kontrolki Kalendarz.

Blokada dat

W zależności do czego chcesz użyć kontrolki Kalendarz, możesz zablokować niektóre daty. Może to być użyteczne do np. aplikacji rezerwującej wydarzenia, w której chcesz się zabezpieczyć, aby użytkownik mógł wybrać tylko daty z dostępnego zakresu. Kontrola Kalendarz standardowo udostępnia taką właściwość poprzez wykorzystanie kolekcji BlackoutDates, która oczywiście jest dostępna zarówno z kodu C# jak i XAML:

<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)));
}
    }
}

W tym przykładzie zademonstrowałem zarówno dodanie blokowanych dat z poziomu XAML, jak i z poziomu kodu C#. Obie metody polegają na dodaniu instancji CalendarDateRange do kolekcji BlackedoutDates.

W XAML zahardkodowałem zakresy blokowanych dat (głównie w celu szybkiego pokazania, że w ten sposób też jest to możliwe), podczas gdy w kodzie C# zrobiłem to już bardzie inteligentnie przez dodanie w pierwszej kolejności całego zakresu dat w przeszłości (wywołując metodę AddDatesInPast()), a następnie dodanie zakresu dat od dzisiaj do jutra.

DisplayMode - wyświetlanie miesięcy i lat

Właściwość DisplayMode może zmienić tryb pracy kontrolki z przejściem na widok miesięcy lub nawet lat. Można to uzyskać za pomocą właściwości DisplayMode, która domyślnie jest ustawiona na Month (Miesiąc) - takie było ustawienie we wszystkich powyższych przykładach. Oto jak to wygląda, jeśli zmienimy wartość tego parametru:

<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>

Ustawiając DisplayMode na Year, możemy teraz wybrać miesiąc w danym roku. Możesz zmieniać rok za pomocą strzałek.

Kontrolka Kalendarz również pozwala na wybór całego roku poprzez ustawienie wartości Decade w parametrze DisplayMode:

<Calendar DisplayMode="Decade" />

Podsumowanie

Jak widać, kontrola Kalendarz jest bardzo wszechstronną kontrolką z dużą ilością opcji i funkcjonalności, wymagającej jedynie minimalnej konfiguracji, aby ją użyć. Jeśli budujesz aplikację z jakąkolwiek funkcją związaną z datami, prawdopodobnie będziesz mógł wykorzystać kontrolkę Kalendarz w taki czy inny sposób.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!