WPFには、カレンダーコントロールが標準であるんですが、
スケジューラ-みたいなことはできないし、あくまで選択された日付を取得するためのものになっています。
常に表示して、カレンダーに対してアクションするようなコントローラーも
需要はあると思うので、標準で使えるようにしてくれればいいのにと思いながらちょっと自作してみます。
今回は新規で専用にプロジェクトを作成します。
VisualStudio2017を起動し、
新規プロジェクトを作成、名前を「CalendarSample」とします。
作成方法などは下記の記事を参考にしていただければ。
Visual Studio 2017 Community のインストールから Hello World
また、スタイルに「MahApps.Metro」を利用するので、
分からなければこちらの記事を参考にしてください。
【WPF】MahApps.Metro で見た目をスタイリッシュにしてみる
App.xaml
<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
<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
<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>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MahApps.Metro.Controls;
namespace CalendarSample
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : MetroWindow
{
private Rectangle selectedRec;
public MainWindow()
{
InitializeComponent();
CalendarGropu1.Header = String.Format("{0:yyyy年MM月}", DateTime.Now);
// 当月の月初を取得
var firstDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
// 曜日番号の取得
int dayOfWeek = (int)firstDate.DayOfWeek;
// 月末を取得
int lastDay = firstDate.AddMonths(1).AddDays(-1).Day;
// 1日から月末までを走査
for (int day = 1; day <= lastDay; day++)
{
// セル位置
int index = (day - 1) + dayOfWeek;
// 横位置
int x = index % 7;
// 縦位置
int y = index / 7;
// 土日は文字色を変更する
Color color = Colors.Black;
if (x == 0)
{
color = Colors.Red;
}
else if (x == 6)
{
color = Colors.Blue;
}
// テキストブロックを生成してグリッドに追加
var tb = new TextBlock()
{
Text = string.Format("{0}", day),
FontSize = 12,
Foreground = new SolidColorBrush(color),
Padding = new Thickness(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);
// 四角形を生成してグリッドに追加
// セルの枠線などを表示し、イベントをハンドリングする用
var rec = new Rectangle();
rec.HorizontalAlignment = HorizontalAlignment.Stretch;
rec.VerticalAlignment = VerticalAlignment.Stretch;
// 背景色を設定しないとイベントを検知できないらしいので透過色を設定
rec.Fill = Brushes.Transparent;
// 枠線を調整
rec.Margin = (x == 6) ? new Thickness(0.0, -1.0, 0.0, 0.0) : new Thickness(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>
void date_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 既に選択されたセルがある場合は初期化
if (selectedRec != null)
{
selectedRec.StrokeDashArray = null;
selectedRec.StrokeThickness = 0;
}
// 枠線に点線をセット
Rectangle rec = sender as Rectangle;
rec.Stroke = Brushes.Black;
DoubleCollection dbc = new DoubleCollection();
dbc.Add(1);
dbc.Add(1);
rec.StrokeDashArray = dbc;
rec.StrokeThickness = 1;
// 選択セルの保持
selectedRec = rec;
}
}
}
ポイントは、
「Grid」を使い枠組みを作成してセルに日付用の「Rectangle」、「TextBlock」を配置することです。
日付セルをクリックすると、枠に点線が表示されるようにしました。
今回はここまでとなります。
次回以降、このカレンダーを使って色々試してみたいと思います。
ではでは。
第1回 | 【WPF】自作カレンダー その1(とりあえず当月を表示) |
第2回 | 【WPF】自作カレンダー その2(動的生成) |
第3回 | 【WPF】自作カレンダー その3(年間カレンダー) |
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント