本例应用.net 2.0中的ChineseLunisolarCalendar类,制作出带中国农历的万年历。
先看看效果图片(已缩小,原始图片为:
http://p.blog.csdn.net/images/p_blog_csdn_net/johnsuna/ChineseLunarCalendar.jpg):
// CalendarWindow.xaml
<Window x:Class="BrawDraw.Com.LunarCalendar.CalendarWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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.cs
using 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();
}
}
}
(未完,待续)星期八旅行网,“走进大自然,爱上星期八”。春游,漂流,上星期八旅行网。http://www.eightour.com