TOC

This article is currently in the process of being translated into Vietnamese (~99% done).

Misc. controls:

The Calendar control

WPF hỗ trợ bảng điều khiển cho phép hiển thị lịch một cách nhanh chóng và thuận tiện. Chỉ đơn giản kéo thả bảng lịch vào trong của sổ ứng dụng của bạn để có một giao diện lịch đầy đủ giống như sau:

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

Lúc này, bạn có thể thấy một danh sách đầy đủ các ngày trong tháng được chọn, bao gồm cả việc nhảy về tháng trước và tới tháng sau bằng cách bấm các mũi tên ở phía trên cùng bảng lịch. Nếu bạn không chọn một ngày nhất định thì tháng hiện tại sẽ hiển thị cùng với ngày hiện tại được đánh dấu chọn.

Kích thước lịch

Bạn có thể sẽ nhận thấy từ ví dụ đầu tiên của chúng tôi rằng Lịch không chiếm hết dung lượng có sẵn. Trên thực tế, ngay cả khi bạn cho chiều rộng và chiều cao lớn, phần lịch thực tế vẫn sẽ chỉ chiếm dung lượng bạn nhìn thấy trên ảnh chụp màn hình và nếu bạn đặt một trong các giá trị rất thấp, lịch sẽ chỉ là một phần có thể nhìn thấy.

Hành vi kích thước cố định này không phải là WPF điển hình, nơi mọi thứ thường kéo dài để lấp đầy không gian có sẵn và sẽ hơi khó chịu khi làm việc nếu bạn có sẵn một không gian được chỉ định cho lịch mà bạn muốn điền vào. May mắn cho chúng tôi, mọi thứ trong WPF đều có thể mở rộng nhưng trong trường hợp điều khiển Lịch, nó cần một chút trợ giúp. Chúng tôi sẽ sử dụng điều khiển Viewbox cho mục đích này:

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

Lưu ý cách điều khiển Lịch bây giờ chia tỷ lệ đến điểm mà nó sử dụng tất cả không gian có sẵn theo chiều rộng. Việc chia tỷ lệ được thực hiện trên tất cả các phần của điều khiển, bao gồm kích thước phông chữ và độ rộng đường viền.

Bạn cũng có thể sẽ nhận thấy rằng điều khiển Lịch không sử dụng hết dung lượng chiều cao có sẵn. Điều này đáng chú ý vì cửa sổ cao hơn chiều rộng và theo mặc định, Viewbox sẽ kéo dài trong khi duy trì tỷ lệ khung hình gốc. Mặc dù vậy, bạn có thể dễ dàng làm cho nó kéo dài để lấp đầy tất cả không gian theo cả hai hướng - chỉ cần thay đổi thuộc tính Stretch từ giá trị Uniform mặc định thành 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>

Bây giờ nó chiếm tất cả không gian có sẵn, theo cả hai hướng. Mặc dù vậy, điều này thường không thích hợp hơn, vì hầu hết các điều khiển và đặc biệt là điều khiển này sẽ trông lạ nếu nó có một bộ kích thước bất thường, ví dụ: Cao 800 pixel và rộng 300 pixel. Chế độ Stretch được đặt thành Uniform (hoặc bỏ đi, vì nó là mặc định) thường là cách để đi.

Tôi muốn giới thiệu bao gồm cả thuộc tính StretchDirection, như đã thấy trong ví dụ này. Nó cho phép chúng tôi xác định rằng các nội dung chỉ nên được tăng hoặc giảm, có thể hữu ích. Chẳng hạn, điều khiển Lịch trở nên khá vô dụng dưới một kích thước nhất định, nơi bạn không còn có thể nhìn thấy nó là gì và để tránh điều đó, bạn có thể đặt StretchDirection thành UpOnly - điều khiển Lịch sẽ không còn được thu nhỏ dưới kích thước mặc định của nó .

Đặt chế độ xem ban đầu bằng DisplayDate

Điều khiển Lịch theo mặc định sẽ hiển thị tháng hiện tại, nhưng bạn có thể thay đổi điều này bằng cách sử dụng thuộc tính DisplayDate. Chỉ cần đặt ngày thành một ngày trong tháng bạn muốn bắt đầu và nó sẽ được phản ánh trong điều khiển:

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

Calendar SelectionMode

Thuộc tính SelectionMode rất thú vị. Bằng cách thay đổi nó từ giá trị mặc định của nó, SingleDate, bạn có thể chọn nhiều ngày hoặc phạm vi ngày. Đây là một ví dụ:

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

Trong SingleRange SelectionMode, bạn có thể chọn toàn bộ phạm vi ngày, bằng cách giữ nút chuột trái và kéo từ ngày này sang ngày khác hoặc bằng cách giữ phím Ctrl hoặc Shift trong khi nhấp vào nhiều ngày, giống như nhiều lựa chọn hoạt động các bộ phận của Windows. Trên ảnh chụp màn hình, tôi đã chọn cả tuần, từ Chủ nhật đến Thứ Hai, nhưng bạn có thể dễ dàng chọn ngày vào giữa tuần và các phạm vi mở rộng trong một tuần.

Chế độ SingleRange chỉ cho phép một phạm vi ngày được chọn mặc dù, giống như tên cho thấy. Điều này có nghĩa là bạn không thể chọn hai ngày không nằm cạnh nhau và bạn không thể chọn nhiều hơn một phạm vi. Nếu bạn muốn điều này, bạn nên chuyển sang lựa chọn MultipleRange:

<Calendar SelectionMode="MultipleRange" />

Với tài sản này, thực sự không có giới hạn cho ngày bạn có thể chọn. Trong trường hợp này, tôi đã chọn tất cả các ngày thứ bảy, tất cả các ngày chủ nhật và một vài ngày trong tuần ở giữa.

Tất nhiên, nếu bạn không muốn có khả năng chọn một hoặc một vài ngày, bạn có thể đặt SelectionMode thành None.

Bây giờ hãy thảo luận về cách chúng tôi có thể làm việc với (các) ngày đã chọn của điều khiển Lịch.

Làm việc với ngày đã chọn

Thuộc tính SelectedDate là tất cả những gì bạn cần nếu bạn chỉ cho phép các lựa chọn duy nhất (xem phần giải thích ở trên về các chế độ lựa chọn). Nó cho phép bạn đặt cả hai và nhận một ngày hiện đang được chọn, từ Mã phía sau cũng như thông qua ràng buộc dữ liệu.

Dưới đây là một ví dụ trong đó chúng tôi đặt ngày đã chọn thành ngày mai từ Mã phía sau và sau đó sử dụng ràng buộc dữ liệu để đọc ngày đã chọn thành điều khiển 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);
}
    }
}

Trong Code-đằng sau, chúng tôi chỉ cần đặt thuộc tính SelectedDate thành ngày hiện tại cộng với một ngày, nghĩa là ngày mai. Sau đó, người dùng có thể thay đổi lựa chọn này bằng cách nhấp vào điều khiển Lịch và thông qua liên kết dữ liệu được thiết lập trong thuộc tính Văn bản của TextBox, thay đổi này sẽ tự động được phản ánh tại đó.

Là một phần thưởng bổ sung, thông qua sự kỳ diệu của liên kết dữ liệu, bạn cũng có thể thay đổi giá trị từ TextBox - chỉ cần nhập ngày hợp lệ và thay đổi sẽ được phản ánh ngay lập tức trong điều khiển Lịch. Nếu bạn nhập một ngày xấu, xác thực ràng buộc tự động thông báo cho bạn về vấn đề:

Làm việc với nhiều ngày đã chọn

Nếu bạn cho phép nhiều hơn một ngày được chọn tại thời điểm đó, bạn sẽ không tìm thấy thuộc tính selected dates hữu ích. Thay vào đó, bạn nên sử dụng Ngày được chọn, là tập hợp các ngày hiện được chọn trong điều khiển Lịch. Thuộc tính này có thể được truy cập từ Mã phía sau hoặc được sử dụng với một ràng buộc, như chúng tôi làm ở đây:

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

Với một ràng buộc đơn giản như thế, giờ đây chúng ta có thể hiển thị danh sách các ngày hiện được chọn.

Nếu bạn muốn phản ứng với những ngày được thay đổi từ Mã phía sau, bạn có thể đăng ký vào sự kiện SelectedDatesChanged của điều khiển Lịch.

Blackout dates

Tùy thuộc vào những gì bạn sử dụng điều khiển Lịch cho, bạn có thể muốn bôi đen một số ngày nhất định. Điều này có thể có liên quan, ví dụ: trong một ứng dụng đặt phòng, nơi bạn muốn ngăn ngày đã được đặt trước được chọn. Điều khiển Lịch hỗ trợ quyền này ngay lập tức thông qua việc sử dụng bộ sưu tập BlackoutDates, tất nhiên bạn có thể sử dụng từ cả XAML và 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)));
}
    }
}

Trong ví dụ này, tôi trình bày cả hai cách thêm ngày bị bôi đen - thông qua XAML và thông qua Code-đằng sau. Cả hai cách đều hoạt động bằng cách thêm phiên bản của CalendarDateRange vào bộ sưu tập BlackedoutDates.

Trong XAML, tôi đang mã hóa các phạm vi ngày (chủ yếu để cho bạn thấy nó cũng có thể được thực hiện theo cách đó), trong khi tôi làm điều gì đó thông minh hơn một chút trong Code-behind, bằng cách trước tiên thêm tất cả các ngày trước vào bộ sưu tập bằng một cuộc gọi vào phương thức AddDatesInPast() và sau đó thêm một phạm vi bao gồm ngày hôm nay và ngày mai.

DisplayMode - hiển thị tháng hoặc năm

Thuộc tính DisplayMode có thể thay đổi điều khiển Lịch từ một nơi mà bạn có thể chọn một ngày thành một nơi mà bạn có thể chọn một tháng hoặc thậm chí một năm. Điều này được thực hiện thông qua thuộc tính DisplayMode, mặc định là Tháng, mà chúng ta đã sử dụng trong tất cả các ví dụ trước. Đây là giao diện nếu chúng ta thay đổi:

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

Bằng cách đặt DisplayMode thành Year, giờ đây chúng ta có thể chọn một tháng của một năm nhất định. Bạn có thể thay đổi năm ở trên cùng, bằng cách sử dụng các mũi tên.

Điều khiển Lịch cũng cho phép chọn cả năm, bằng cách sử dụng giá trị Decade cho thuộc tính DisplayMode:

<Calendar DisplayMode="Decade" />

Tổng kết

Như bạn có thể thấy, điều khiển Lịch là một điều khiển rất linh hoạt với nhiều tùy chọn và chức năng, chỉ yêu cầu tối thiểu cấu hình để sử dụng. Nếu bạn đang xây dựng một ứng dụng với bất kỳ loại chức năng nào liên quan đến ngày, bạn có thể sẽ có thể sử dụng điều khiển Lịch, bằng cách này hay cách khác.


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!