原文: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. [Nuxt] Display Vuex Data Differently in Each Page of Nuxt and Vue.js

    You often use the same data in different ways across pages. This lesson walks you through setting up ...

  2. WIN32得到HWND

    HWND hwndFound //= FindWindow(_T("RC352_Win32"),NULL); = GetConsoleWindow();

  3. springboot(十四):springboot整合shiro-登录认证和权限管理(转)

    springboot(十四):springboot整合shiro-登录认证和权限管理 .embody{ padding:10px 10px 10px; margin:0 -20px; border-b ...

  4. 微服务API模拟框架frock介绍

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/02/introducing-frock Urban Airship是一家帮助 ...

  5. LOG4J中日志级别的使用

    <logger name="demo-log" additivity="false"> <level value="${log.le ...

  6. wPaint在线绘图插件

    wPaint在线绘图插件 一.总结 一句话总结: 1.搜画图插件的时候关键词应该搜什么? jquery画图插件 js画图插件 jquery绘图插件 这些 二.在线绘图插件--wPaint 的实际应用 ...

  7. 使用oschina的gitserver

    1.概要 事实上oschina的gitserver与github的几乎相同.只是既然是中国的gitserver,那么速度应该更快一些吧 2.注冊 链接https://git.oschina.net/, ...

  8. 复制相关参数学习笔记--slave上的参数

    server_id server_uuid   relay_log io_thread 读取过来的本地日志. relaylog文件名前缀,可以是全路径.   relay_log_index relay ...

  9. tky项目第②个半月总结

    在上一篇半月总结中,介绍了tky项目的整体架构.项目的进展情况.项目的优势与开发中存在的问题等.今天来聊聊这半个月中,项目中发生的事情. 在这半个月中,项目中有了较大的突破:成功通过了国家评測中心的測 ...

  10. js进阶 10-9 -of-type型子元素伪类选择器

    js进阶 10-9 -of-type型子元素伪类选择器 一.总结 一句话总结:三种和first.last等有关的选择器. 1.:first和:first-child和:first-of-type的区别 ...