【WPF】自作カレンダー その1(とりあえず当月を表示)
おはようございます。
カレンダーコントロールは標準であるんですが、
スケジューラ-みたいなことはできないし、あくまで選択された日付を取得するためのものになっています。
常に表示して、カレンダーに対してアクションするようなコントローラーも
需要はあると思うので、標準で使えるようにしてくれればいいのにと思いながらちょっと自作してみます。
今回は新規で専用にプロジェクトを作成します。
スポンサーリンク
プロジェクト作成
VisualStudio2017を起動し、
新規プロジェクトを作成、名前を「CalendarSample」とします。
作成方法などは下記の記事を参考にしていただければ。
また、スタイルに「MahApps.Metro」を利用するので、
分からなければこちらの記事を参考にしてください。
プログラム実装
スタイルの設定
App.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <Application x:Class="CalendarSample.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CalendarSample" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" /> <!-- Accent and AppTheme setting --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application> |
MahApps.Metroのスタイル設定を記述します。
StyleDic.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 | <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:local="clr-namespace:WpfApp1.Style"> <!-- グループ:通常--> <Style x:Key="gp-normal"TargetType="GroupBox" > <Setter Property="VerticalAlignment"Value="Top"/> <Setter Property="HorizontalAlignment"Value="Left"/> <Setter Property="Background"Value="#FFFFFFFF"/> <Setter Property="Foreground"Value="#FF777777"/> </Style> </ResourceDictionary> |
プロジェクト直下に「Style」ディレクトリを追加し、上記ファイルを作成します。
画面の作成
MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | <Mah:MetroWindow x:Class="CalendarSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:CalendarSample" xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" GlowBrush="{DynamicResource AccentColorBrush}" mc:Ignorable="d" WindowStartupLocation="CenterScreen" Title="カレンダーサンプル"Height="350"Width="525"> <Window.Resources> <ResourceDictionary Source="/Style/StyleDic.xaml"/> </Window.Resources> <Grid> <GroupBox x:Name="CalendarGropu1"Header=""HorizontalAlignment="Left"Height="300"Margin="10,10,0,0"VerticalAlignment="Top"Width="497"Style="{StaticResource gp-normal}"> <Grid x:Name="CalendarGrid"HorizontalAlignment="Left"Height="258"Margin="10,10,0,0"VerticalAlignment="Top"Width="467"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="1*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="20" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> </Grid.RowDefinitions> <Rectangle Stroke="Black"StrokeThickness="1"Grid.ColumnSpan="7"Grid.RowSpan="7"/> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="0"VerticalAlignment="Stretch"Margin="1 1 0 0"Panel.ZIndex="0" /> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="1"VerticalAlignment="Stretch"Margin="1 1 0 0"Panel.ZIndex="0"/> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="2"VerticalAlignment="Stretch"Margin="1 1 0 0"Panel.ZIndex="0"/> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="3"VerticalAlignment="Stretch"Margin="1 1 0 0"Panel.ZIndex="0"/> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="4"VerticalAlignment="Stretch"Margin="1 1 0 0"Panel.ZIndex="0"/> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="5"VerticalAlignment="Stretch"Margin="1 1 0 0"Panel.ZIndex="0"/> <Rectangle Fill="#ff8000"HorizontalAlignment="Stretch"Grid.Row="0"Grid.Column="6"VerticalAlignment="Stretch"Margin="1 1 1 0"Panel.ZIndex="0"/> <Rectangle Height="1"Stroke="Black"StrokeThickness="1"VerticalAlignment="Bottom"Grid.ColumnSpan="7"/> <Label Content="日"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="0"VerticalAlignment="Center"FontSize="11"Padding="0"/> <Label Content="月"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="1"VerticalAlignment="Center"FontSize="11"Padding="0"/> <Label Content="火"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="2"VerticalAlignment="Center"FontSize="11"Padding="0"/> <Label Content="水"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="3"VerticalAlignment="Center"FontSize="11"Padding="0"/> <Label Content="木"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="4"VerticalAlignment="Center"FontSize="11"Padding="0"/> <Label Content="金"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="5"VerticalAlignment="Center"FontSize="11"Padding="0"/> <Label Content="土"HorizontalAlignment="Center"Grid.Row="0"Grid.Column="6"VerticalAlignment="Center"FontSize="11"Padding="0"/> </Grid> </GroupBox> </Grid> </Mah:MetroWindow> |
コードビハインドの実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Data; usingSystem.Windows.Documents; usingSystem.Windows.Input; usingSystem.Windows.Media; usingSystem.Windows.Media.Imaging; usingSystem.Windows.Navigation; usingSystem.Windows.Shapes; usingMahApps.Metro.Controls; namespaceCalendarSample { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> publicpartial classMainWindow:MetroWindow { privateRectangle selectedRec; publicMainWindow() { InitializeComponent(); CalendarGropu1.Header=String.Format("{0:yyyy年MM月}",DateTime.Now); // 当月の月初を取得 varfirstDate=newDateTime(DateTime.Now.Year,DateTime.Now.Month,1); // 曜日番号の取得 intdayOfWeek=(int)firstDate.DayOfWeek; // 月末を取得 intlastDay=firstDate.AddMonths(1).AddDays(-1).Day; // 1日から月末までを走査 for(intday=1;day<=lastDay;day++) { // セル位置 intindex=(day-1)+dayOfWeek; // 横位置 intx=index%7; // 縦位置 inty=index/7; // 土日は文字色を変更する Color color=Colors.Black; if(x==0) { color=Colors.Red; } elseif(x==6) { color=Colors.Blue; } // テキストブロックを生成してグリッドに追加 vartb=newTextBlock() { Text=string.Format("{0}",day), FontSize=12, Foreground=newSolidColorBrush(color), Padding=newThickness(0,10,10,0), HorizontalAlignment=HorizontalAlignment.Right, VerticalAlignment=VerticalAlignment.Top }; this.CalendarGrid.Children.Add(tb); tb.SetValue(Grid.ColumnProperty,x); tb.SetValue(Grid.RowProperty,y+1); // 四角形を生成してグリッドに追加 // セルの枠線などを表示し、イベントをハンドリングする用 varrec=newRectangle(); rec.HorizontalAlignment=HorizontalAlignment.Stretch; rec.VerticalAlignment=VerticalAlignment.Stretch; // 背景色を設定しないとイベントを検知できないらしいので透過色を設定 rec.Fill=Brushes.Transparent; // 枠線を調整 rec.Margin=(x==6)?newThickness(0.0,-1.0,0.0,0.0):newThickness(0.0,-1.0,-1.0,0.0); // イベント設定 rec.MouseLeftButtonDown+=date_MouseLeftButtonDown; this.CalendarGrid.Children.Add(rec); rec.SetValue(Grid.ColumnProperty,x); rec.SetValue(Grid.RowProperty,y+1); } } /// <summary> /// セル(日)をクリックした際のイベントハンドラ. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> voiddate_MouseLeftButtonDown(objectsender,MouseButtonEventArgse) { // 既に選択されたセルがある場合は初期化 if(selectedRec!=null) { selectedRec.StrokeDashArray=null; selectedRec.StrokeThickness=0; } // 枠線に点線をセット Rectangle rec=sender asRectangle; rec.Stroke=Brushes.Black; DoubleCollection dbc=newDoubleCollection(); dbc.Add(1); dbc.Add(1); rec.StrokeDashArray=dbc; rec.StrokeThickness=1; // 選択セルの保持 selectedRec=rec; } } } |
ポイントは、
「Grid」を使い枠組みを作成してセルに日付用の「Rectangle」、「TextBlock」を配置することです。
起動してみる
日付セルをクリックすると、枠に点線が表示されるようにしました。
まとめ
今回はここまでとなります。
次回以降、このカレンダーを使って色々試してみたいと思います。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません