原文:WPF中制作带中国农历的万年历

本例应用.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

WPF中制作带中国农历的万年历的更多相关文章

  1. WPF中制作立体效果的文字或LOGO图形(续)

    原文:WPF中制作立体效果的文字或LOGO图形(续) 上篇"WPF中制作立体效果的文字或LOGO图形"(http://blog.csdn.net/johnsuna/archive/ ...

  2. WPF中制作立体效果的文字或LOGO图形

    原文:WPF中制作立体效果的文字或LOGO图形 较久之前,我曾写过一篇:"WPF绘制党徽(立体效果,Cool) "的博文.有感兴趣的朋友来EMAIL问是怎么制作的?本文解决此类问题 ...

  3. WPF中制作无边框窗体

    原文:WPF中制作无边框窗体 众所周知,在WinForm中,如果要制作一个无边框窗体,可以将窗体的FormBorderStyle属性设置为None来完成.如果要制作成异形窗体,则需要使用图片或者使用G ...

  4. 在WPF中制作正圆形公章

    原文:在WPF中制作正圆形公章 之前,我利用C#与GDI+程序制作过正圆形公章(利用C#制作公章 ,C#制作公章[续])并将它集成到一个小软件中(个性印章及公章的画法及实现),今天我们来探讨一下WPF ...

  5. 01.WPF中制作无边框窗体

    [引用:]http://blog.csdn.net/johnsuna/article/details/1893319   众所周知,在WinForm中,如果要制作一个无边框窗体,可以将窗体的FormB ...

  6. WPF中实现多选ComboBox控件

    在WPF中实现带CheckBox的ComboBox控件,让ComboBox控件可以支持多选. 将ComboBox的ItemsSource属性Binding到一个Book的集合, public clas ...

  7. WPF中桌面屏保的制作(主要代码)

    原文:WPF中桌面屏保的制作(主要代码) 制作要点:(1) 使用System.Windows.Threading.DispatcherTimer;(2) 将Window属性设置为:      this ...

  8. 在WPF设计工具Blend2中制作立方体图片效果

    原文:在WPF设计工具Blend2中制作立方体图片效果 ------------------------------------------------------------------------ ...

  9. 整理:WPF中应用附加事件制作可以绑定命令的其他事件

    原文:整理:WPF中应用附加事件制作可以绑定命令的其他事件 目的:应用附加事件的方式定义可以绑定的事件,如MouseLeftButton.MouseDouble等等 一.定义属于Control的附加事 ...

随机推荐

  1. IOS计算两点之间的距离

    //广州经纬度 CLLocationCoordinate2D guangZhouLocation; guangZhouLocation.latitude = 23.20; guangZhouLocat ...

  2. 【例题3-3 UVA - 401】Palindromes

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 如果一个字符没有对应的镜像,那么它对应的是一个空格. 然后注意 aba这种情况. 这种情况下b也要查一下它的镜像是不是和b一样. [ ...

  3. 单选框radio改变事件详解(用的jquery的radio的change事件)

    单选框radio改变事件详解(用的jquery的radio的change事件) 一.总结 1.用的jquery的radio的change事件:当元素的值发生改变时,会发生 change 事件,radi ...

  4. 微擎 plugin 时间插件 图片上传插件不显示 报错 影响下面执行

    可能是版本更新导致的,之前可能不需要 load()->func('tpl');这个方法 现在加上 load()->func('tpl');应该就可以了

  5. 有关下拉列表、复选框、单选按钮、iframe等jquery处理方法

    1.jquery验证复选框互斥选项,代码如下: //验证复选框中的互斥选项 function checkData(name, val1, val2){ //获取所有checkbox值 var chec ...

  6. JQuery中Ajax详细参数使用案例

    JQuery中Ajax详细参数使用案例 参考文档:http://www.jb51.net/shouce/jquery1.82/ 参考文档:http://jquery.cuishifeng.cn/jQu ...

  7. Home界面的启动

    继上篇文章Launcher进程的启动,我们继续分析Home界面的启动. public final class ActivityThread { ...... public static final v ...

  8. Android 设置alpha值来制作透明与渐变效果的实例

    Android系统支持的颜色是由4个值组成的,前3个为RGB,也就是我们常说的三原色(红.绿.蓝),最后一个值是A,也就是Alpha.这4个值都在0~255之间.颜色值越小,表示该颜色越淡,颜色值越大 ...

  9. 搭建微信小程序开发环境

    1.下载开发工具 点击进入下载地址选择和自己电脑匹配的安装包,并安装: image.png 安装完成后出现应用icon: image.png 2.创建项目 能够扫码登录的前提是微信号已经注册了小程序, ...

  10. 【t030】数字构造

    Time Limit: 3 second Memory Limit: 256 MB [问题描述] 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行 ...