本例应用.net 2.0中的ChineseLunisolarCalendar类,制作出带中国农历的万年历。
先看看效果图片(已缩小,原始图片为:
):// CalendarWindow.xaml<Window x:Class="BrawDraw.Com.LunarCalendar.CalendarWindow" xmlns="" xmlns:x="" xmlns:properties="clr-namespace:BrawDraw.Com.LunarCalendar.Properties" Title="中国万年历" Height="560" Width="780" AllowsTransparency="True" Opacity="0.95" Visibility="Collapsed" WindowStyle="None" HorizontalAlignment="Center" FontSize="16" x:Name="calendarWindow"> <Window.Resources> <Style x:Key="Font"> <Setter Property="Control.FontFamily" Value="Arial" /> </Style> </Window.Resources> <Grid Height = "530" Opacity ="1" Visibility="Visible" Style="{StaticResource Font}"> <StackPanel Height="37" Margin="19,0,129,0" Name="stackPanel1" VerticalAlignment="Top" Orientation="Horizontal" /> <ListBox Margin="19,39,129,35" Name="CalendarListBox" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" FontSize="21"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Name="CalendarDisplayUniformGrid" Columns="7" HorizontalAlignment="Center" IsItemsHost="True" Width="600" Height="450" VerticalAlignment="Center"> </UniformGrid> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox> <Button Height="35" HorizontalAlignment="Right" Margin="0,165,15,0" Name="PreviousYearButton" VerticalAlignment="Top" Width="107" Content="{x:Static properties:Resources.PreviousYearText}"></Button> <Button HorizontalAlignment="Right" Margin="0,223,15,0" Name="NextYearButton" Width="107" Content="{x:Static properties:Resources.NextYearText}" Height="35" VerticalAlignment="Top"></Button> <Button Height="35" HorizontalAlignment="Right" Margin="0,155,15,160" Name="PreviousMonthButton" VerticalAlignment="Bottom" Width="107" Content="{x:Static properties:Resources.PreviousMonthText}"></Button> <Button Height="35" HorizontalAlignment="Right" Margin="0,0,15,100" Name="NextMonthButton" VerticalAlignment="Bottom" Width="107" Content="{x:Static properties:Resources.NextMonthText}"></Button> <Button Height="35" HorizontalAlignment="Right" Margin="0,0,15,37" Name="CurrentMonthButton" VerticalAlignment="Bottom" Width="107" Content="{x:Static properties:Resources.CurrentMonthText}"></Button> <Button Height="37" Name="btnSaveImageFile" Width="105" Click="btnSaveImageFile_Click" Canvas.Left="639" Canvas.Top="274" HorizontalAlignment="Right" Margin="0,0,15,214" VerticalAlignment="Bottom">Save Image</Button> <Label Height="26" HorizontalAlignment="Left" Margin="28,0,0,11" Name="lblDisplayMonthName" VerticalAlignment="Bottom" Width="168">Label</Label> <Canvas x:Name="minNormalMaxButton" Height="37" VerticalAlignment="Top" HorizontalAlignment="Right" Width="122"> <Button Height="26" Canvas.Left="82" Width="25" Canvas.Top="8" Name="CloseButton">X</Button> <Button Canvas.Left="52" Canvas.Top="8" Height="26" Width="25" Name="MinButton">—</Button> </Canvas> </Grid></Window>// CalendarWindow.xaml.csusing System;using System.Collections.Generic;using System.IO;//using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Globalization;using System.Windows.Controls.Primitives;namespace BrawDraw.Com.LunarCalendar
{ /// <summary> /// Interaction logic for CalendarWindow.xaml /// </summary> public partial class CalendarWindow : Window { private ICalendar mainCalendar; private ICalendar subsidiaryCalendar;private int year;
private int month; private int day;private CultureInfo localCultureInfo = new CultureInfo(CultureInfo.CurrentUICulture.ToString());
private UniformGrid calendarDisplayUniformGrid;private string[] WeekDays = new string[]{
LunarCalendar.Properties.Resources.Sunday, LunarCalendar.Properties.Resources.Monday, LunarCalendar.Properties.Resources.Tuesday, LunarCalendar.Properties.Resources.Wednesday, LunarCalendar.Properties.Resources.Thursday, LunarCalendar.Properties.Resources.Friday, LunarCalendar.Properties.Resources.Saturday };public CalendarWindow()
{ InitializeComponent();this.Loaded += WindowOnLoad;
this.MouseLeftButtonDown += WindowOnMove; //this.CalendarListBox.SelectionChanged += SelectedDateOnDisplay; this.CloseButton.Click += WindowOnClose; this.MinButton.Click += WindowOnMin;this.Background = Brushes.Black;
this.ResizeMode = ResizeMode.CanMinimize; this.lblDisplayMonthName.Foreground = Brushes.White; this.CalendarListBox.Foreground = Brushes.White; this.CalendarListBox.Background = Brushes.Black; this.CalendarListBox.Padding = new Thickness(0, 0, 0, 0);year = DateTime.Now.Year;
month = DateTime.Now.Month; day = DateTime.Now.Day;mainCalendar = new StandardGregorianCalendar();
subsidiaryCalendar = localCultureInfo.ToString() == "zh-CN" ? new ChineseLunarCalendar() : null;
WeekdayLabelsConfigure();
TimeSwitchButtonsConfigure(); }public void DisplayCalendar(int year, int month)
{ int dayNum = DateTime.DaysInMonth(year, month); calendarDisplayUniformGrid = GetCalendarUniformGrid(CalendarListBox);DateTime dateTime = new DateTime(year, month, 1);
int firstDayIndex = (int)(dateTime.DayOfWeek); calendarDisplayUniformGrid.FirstColumn = firstDayIndex; if (firstDayIndex + dayNum > 35) { calendarDisplayUniformGrid.Rows = 6; } else if (firstDayIndex + dayNum > 28) { calendarDisplayUniformGrid.Rows = 5; } else { calendarDisplayUniformGrid.Rows = 4; } List<DateEntry> mainDateList = mainCalendar.GetDaysOfMonth(year, month); List<DateEntry> subsidiaryDateList = null; if (subsidiaryCalendar != null) { subsidiaryDateList = subsidiaryCalendar.GetDaysOfMonth(year, month); }for (int i = 0; i < dayNum; i++)
{ bool isCurrentDay = (dateTime.Date == DateTime.Now.Date); Label mainDateLabel = new Label(); mainDateLabel.HorizontalAlignment = HorizontalAlignment.Center; mainDateLabel.VerticalAlignment = VerticalAlignment.Center; if (isCurrentDay) { mainDateLabel.Background = Brushes.Orange; } else { mainDateLabel.Background = Brushes.Black; }mainDateLabel.Padding = new Thickness(0, 0, 0, 0);
mainDateLabel.Margin = new Thickness(0, 0, 0, 0);Label hiddenLabel = new Label();
hiddenLabel.HorizontalAlignment = HorizontalAlignment.Stretch; hiddenLabel.VerticalAlignment = VerticalAlignment.Stretch; hiddenLabel.Visibility = Visibility.Collapsed;mainDateLabel.FontSize = (localCultureInfo.ToString() == "zh-CN") ? 31 : 42;
if (IsWeekEndOrFestival(ref dateTime, mainDateList, i))
{ mainDateLabel.Foreground = Brushes.Red; if (mainDateList[i].IsFestival) { hiddenLabel.Content = mainDateList[i].Text; } } else { hiddenLabel.Content = ""; mainDateLabel.Foreground = Brushes.White; }mainDateLabel.Content = mainDateList[i].DateOfMonth.ToString(NumberFormatInfo.CurrentInfo);
Label subsidiaryDateLabel = null;
if (subsidiaryDateList != null) { subsidiaryDateLabel = new Label(); subsidiaryDateLabel.HorizontalAlignment = HorizontalAlignment.Center; subsidiaryDateLabel.VerticalAlignment = VerticalAlignment.Center; if (isCurrentDay) { subsidiaryDateLabel.Background = Brushes.Orange; } else { subsidiaryDateLabel.Background = Brushes.Black; } subsidiaryDateLabel.Padding = new Thickness(0, 0, 0, 0); subsidiaryDateLabel.FontSize = 21;subsidiaryDateLabel.Foreground = subsidiaryDateList[i].IsFestival ? Brushes.Red : Brushes.White;
subsidiaryDateLabel.Content = subsidiaryDateList[i].Text; }StackPanel stackPanel = new StackPanel();
stackPanel.HorizontalAlignment = HorizontalAlignment.Center; stackPanel.VerticalAlignment = VerticalAlignment.Center;stackPanel.Children.Add(hiddenLabel);
stackPanel.Children.Add(mainDateLabel); if (subsidiaryDateLabel != null) { stackPanel.Children.Add(subsidiaryDateLabel); } Button dayButton = new Button(); dayButton.HorizontalAlignment = HorizontalAlignment.Center; dayButton.VerticalAlignment = VerticalAlignment.Center; dayButton.Content = stackPanel; dayButton.BorderBrush = Brushes.Red; dayButton.BorderThickness = new Thickness(1); dayButton.Background = Brushes.Black; dayButton.Width = 68;CalendarListBox.Items.Add(dayButton);
//Display the current day in another color if (isCurrentDay) { mainDateLabel.Foreground = Brushes.Red; if (subsidiaryDateLabel != null) { subsidiaryDateLabel.Foreground = Brushes.Red; } dayButton.Background = Brushes.Orange; } dateTime = dateTime.AddDays(1); }}
private static bool IsWeekEndOrFestival(ref DateTime dateTime, List<DateEntry> mainDateList, int i)
{ return ((int)dateTime.DayOfWeek == 6) || ((int)dateTime.DayOfWeek == 0) || mainDateList[i].IsFestival; }private void HighlightCurrentDate()
{ UIElementCollection dayCollection = calendarDisplayUniformGrid.Children; ListBoxItem today; int index = DateTime.Now.Day - 1; today = (ListBoxItem)(dayCollection[index]); today.Foreground = Brushes.Blue; }private UniformGrid GetCalendarUniformGrid(DependencyObject uniformGrid)
{ UniformGrid tempGrid = uniformGrid as UniformGrid;if (tempGrid != null)
{ return tempGrid; }for (int i = 0; i < VisualTreeHelper.GetChildrenCount(uniformGrid); i++)
{ DependencyObject gridReturn = GetCalendarUniformGrid(VisualTreeHelper.GetChild(uniformGrid, i)); if (gridReturn != null) { return gridReturn as UniformGrid; } } return null; }private void WeekdayLabelsConfigure()
{ Label tempLabel;for (int i = 0; i < 7; i++)
{ tempLabel = new Label(); tempLabel.Width = 650 / 7; tempLabel.FontSize = 21;tempLabel.HorizontalAlignment = HorizontalAlignment.Stretch;
tempLabel.HorizontalContentAlignment = HorizontalAlignment.Center; tempLabel.VerticalAlignment = VerticalAlignment.Stretch; tempLabel.VerticalContentAlignment = VerticalAlignment.Center;tempLabel.Foreground = (i == 0 || i == 6) ? Brushes.Red : Brushes.White;
tempLabel.Content = WeekDays[i]; this.stackPanel1.Children.Add(tempLabel); } }private void TimeSwitchButtonsConfigure()
{ PreviousYearButton.Click += PreviousYearOnClick; NextYearButton.Click += NextYearOnClick; PreviousMonthButton.Click += PreviousMonthOnClick; NextMonthButton.Click += NextMonthOnClick; CurrentMonthButton.Click += CurrentMonthOnClick; }//Event handler
private void WindowOnLoad(Object sender, EventArgs e) { DisplayCalendar(year, month); lblDisplayMonthName.Content = DateTime.Now.ToShortDateString(); HighlightCurrentDate(); }private void WindowOnClose(Object sender, EventArgs e)
{ this.Close(); }private void WindowOnMin(Object sender, EventArgs e)
{ this.WindowState = WindowState.Minimized; }private void WindowOnMove(Object sender, EventArgs e)
{ this.DragMove(); }private void UpdateMonth()
{ CalendarListBox.BeginInit(); CalendarListBox.Items.Clear(); DisplayCalendar(year, month); CalendarListBox.EndInit(); lblDisplayMonthName.Content = (new DateTime(year, month, 1)).ToString("Y", localCultureInfo); CalendarListBox.SelectedItem = null;//Check the calendar range and disable corresponding buttons
CheckRange(); }private void PreviousYearOnClick(Object sender, RoutedEventArgs e)
{ if (year <= 1902) { return; }year -= 1;
UpdateMonth(); }private void NextYearOnClick(Object sender, RoutedEventArgs e)
{ if (year >= 2100) { return; }year += 1;
UpdateMonth(); }private void PreviousMonthOnClick(Object sender, RoutedEventArgs e)
{ if (month == 1 && year == 1902) { return; }month -= 1;
if (month == 0) { month = 12; year--; } UpdateMonth(); }private void NextMonthOnClick(Object sender, RoutedEventArgs e)
{ if (month == 12 && year == 2100) { return; } month += 1; if (month > 12) { month = 1; year++; } UpdateMonth(); }private void CurrentMonthOnClick(Object sender, RoutedEventArgs e)
{ year = DateTime.Now.Year; month = DateTime.Now.Month; day = DateTime.Now.Day;UpdateMonth();
HighlightCurrentDate(); }private void CheckRange()
{ //The calendar range is between 01/01/1902 and 12/31/2100 PreviousYearButton.IsEnabled = (year <= 1902) ? false : true; PreviousMonthButton.IsEnabled = (month == 01 && year <= 1902) ? false : true; NextYearButton.IsEnabled = (year >= 2100) ? false : true; NextMonthButton.IsEnabled = (month == 12 && year >= 2100) ? false : true; }private void btnSaveImageFile_Click(object sender, RoutedEventArgs e)
{ SavePhoto(@"c:/ChineseLunarCalendar.jpg", this.calendarWindow); MessageBox.Show("OK"); }protected void SavePhoto(string fileName, Visual visual)
{ // 利用RenderTargetBitmap对象,以保存图片 RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)this.Width, (int)this.Height, 96, 96, PixelFormats.Pbgra32); renderBitmap.Render(visual);// 利用JpegBitmapEncoder,对图像进行编码,以便进行保存
JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); // 保存文件 FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite); encoder.Save(fileStream); // 关闭文件流 fileStream.Close(); } }}(未完,待续)星期八旅行网,“走进大自然,爱上星期八”。春游,漂流,上星期八旅行网。