WindowsPhone Advent Calender 2013 22日目担当のいっちゅうです。

Advent Calendarってことで
WindowsPhoneでカレンダーっぽいものを作ってみようかな?
ちょっと探してみたけど、今まで同じような記事書いてる人いないみたいだし。

完成イメージはこんな感じです。
WPAC10

今回はWindowsPhone8.0SDK(VisualStudio Express 2012 for WindowsPhone )が入っていることが前提です。
試したい人でまだWindowsPhone8.0 SDKが入っていない人は入れてください。ここ
(インストールにはWindows8の64bit版が必要です。)
ちなみにWindowsPhoneSDK7.1~7.8でもほぼ同じはずです。

ではさっそく。(C#で説明させて頂きます)
ソリューション作るよー。
標準テンプレートの「Windows Phoneアプリ」選択し、ソリューション名を決めます。
(ここでは「Calendar」にします)
WPAC01
WPAC02

ページ名でかっ!
WPAC03

ってことでちょっといじります。
Styleを消してフォントサイズを30、名前を付けます。

<TextBlock x:Name="YearMonth"  Text="ページ名" Margin="9,-7,0,0" FontSize="30"/>

WPAC04

ローテーションを横画面にも対応させておきます。
WPAC05

メインコンテンツのGridのColumnを日月火水木金土の7列、
Rowを7行に分割しておきます。

1行目は曜日ラベルで、日付のマスは最大でも6行あれば1ヶ月分を表示できます。
1日が土曜日だとして、1ヶ月は最大31日のため、1引いて30日分を7で割ると4余り2、
つまり5行分ですね。最初の1日の1行を足して6行となるわけです。
以下をGridの中にコピペします。

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="50*"/>
    <ColumnDefinition Width="50*"/>
    <ColumnDefinition Width="50*"/>
    <ColumnDefinition Width="50*"/>
    <ColumnDefinition Width="50*"/>
    <ColumnDefinition Width="50*"/>
    <ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
    <RowDefinition Height="30*"/>
    <RowDefinition Height="80*"/>
    <RowDefinition Height="80*"/>
    <RowDefinition Height="80*"/>
    <RowDefinition Height="80*"/>
    <RowDefinition Height="80*"/>
    <RowDefinition Height="80*"/>
</Grid.RowDefinitions>

※好みの問題ですがデバイスのテーマもライトに変えます。
WPAC06

曜日のヘッダーをXAMLで書きましょう。

<Border BorderThickness="1" Grid.Row="0"  Grid.Column="0" Margin="-1,-1,0,0" Background="#FFE7998E" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="日" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>
<Border BorderThickness="1" Grid.Row="0"  Grid.Column="1" Margin="-1,-1,0,0" Background="#FFAAAAAA" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="月" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>
<Border BorderThickness="1" Grid.Row="0"  Grid.Column="2" Margin="-1,-1,0,0" Background="#FFAAAAAA" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="火" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>
<Border BorderThickness="1" Grid.Row="0"  Grid.Column="3" Margin="-1,-1,0,0" Background="#FFAAAAAA" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="水" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>
<Border BorderThickness="1" Grid.Row="0"  Grid.Column="4" Margin="-1,-1,0,0" Background="#FFAAAAAA" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="木" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>
<Border BorderThickness="1" Grid.Row="0"  Grid.Column="5" Margin="-1,-1,0,0" Background="#FFAAAAAA" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="金" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>
<Border BorderThickness="1" Grid.Row="0"  Grid.Column="6" Margin="-1,-1,0,0" Background="#FF87A3D0" BorderBrush="#FFFFFFFF">
    <TextBlock HorizontalAlignment="Center" Text="土" VerticalAlignment="Center" Foreground="#FFFFFFFF"/>
</Border>

WPAC07_2

XAML部分はここで終わりです。以降はコードビハインドで描画します。
WPAC08

今回は面倒なので全部コンストラクターに書いています。

変数を作っておきます。

//マイナス何日するのか記憶する変数
int int_StartDay = 0;

//現在の日付を記憶する変数(今月は0)
DateTime dt_Now = DateTime.Now.AddMonths(0);

ページ名に年月を入れます。

//タイトルに○年○月と入れる
YearMonth.Text = dt_Now.ToString("yyyy年MM月");

1日の曜日を調べます。(どのマスから開始するか)
まず今月1日の日付型変数を作っておきます。

//1日の曜日を調べる
DateTime dt_FirstDay = DateTime.Parse(dt_Now.ToString("yyyy/MM/01 00:00:00"));

1日の曜日を調べて最初のマスをマイナス何日すればいいか変数に代入する。

//1日の曜日を調べて最初のマスをマイナス何日すればいいか変数に代入する。
switch (dt_FirstDay.DayOfWeek)
{
    case DayOfWeek.Sunday:
        int_StartDay = 0;
        break;
    case DayOfWeek.Monday:
        int_StartDay = 1;
        break;
    case DayOfWeek.Tuesday:
        int_StartDay = 2;
        break;
    case DayOfWeek.Wednesday:
        int_StartDay = 3;
        break;
    case DayOfWeek.Thursday:
        int_StartDay = 4;
        break;
    case DayOfWeek.Friday:
        int_StartDay = 5;
        break;
    case DayOfWeek.Saturday:
        int_StartDay = 6;
        break;
}

最初のマスの日付を算出してカウントを初期化しておきます。

//最初のマスの日付を設定する
dt_Now = dt_FirstDay.AddDays(-int_StartDay);
//カウント(初期化)
int count = 0;

6行、7列をループさせるfor文を書きます。

for (int y = 1; y <= 6; ++y) // Row 6行
{
    for (int x = 0; x <= 6; ++x) // Column 日~土
    {
    }
}

以降for文ループの中に記述します。
まず1マスのボーダー線を設定します。

//ボーダー線を作成
Border b = new Border();

//パネルの子供にする
ContentPanel.Children.Add(b);

//パネルのグリッド位置設定
System.Windows.Controls.Grid.SetColumn(b, x);
System.Windows.Controls.Grid.SetRow(b, y);

//線の太さ
Thickness t = new Thickness(1);
b.BorderThickness = t;

//線のマージンを設定
Thickness t2 = new Thickness(-1,-1,0,0);
b.Margin = t2;

//ボーダー線の色を設定
b.BorderBrush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 170, 170, 170));

バックカラーを設定します。

//バックカラーを設定。今月以外は灰色、日曜日、祝日はピンク、土曜日は水色にする。
if (dt_Now.AddDays(count).ToString("yyyy年MM月") == YearMonth.Text) 
{
    //曜日チェック
    switch (dt_Now.AddDays(count).DayOfWeek)
    {
        case DayOfWeek.Sunday:
            //日曜日はピンク
            b.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 247, 223, 223));
            break;
        case DayOfWeek.Saturday:
            //土曜日は水色
            b.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 223, 223, 247));
            break;
        default:
            //平日
             b.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 255, 255));
            break;
    }

}else{

    //当月以外は灰色
    b.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 230, 230, 230));

}

マスに日付を入れます。
予定などを入れたい場合は日付の後ろに付けます。

//テキストブロックを作成
TextBlock txt = new TextBlock();

//ボーダーの子供にする
b.Child = txt;

//テキストブロックの折り返しを設定
txt.TextWrapping = TextWrapping.Wrap;

//マージンを設定。線の内側3ピクセル分にする
Thickness t3 = new Thickness(3);
txt.Margin = t3;

//フォントサイズを設定する
txt.FontSize = 16;

//文字の色を設定する
txt.Foreground = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 0, 0, 0));

//文字の水平位置を左にする
txt.TextAlignment = TextAlignment.Left;

//文字の垂直位置を上にする
txt.VerticalAlignment = VerticalAlignment.Top;

//文字を設定。1行目は日付の数字。改行して好きな文字を入れる。
txt.Text = dt_Now.AddDays(count).ToString("%d") + "n";

最後に日付をカウントアップします。

//カウントを+1する。
count += 1;

デバッグすると以下のように表示されると思います。
WPAC09

ただしこれだけだと、祝日が表示されていません。
「HolidayChecker.cs」クラスをプロジェクトにに追加します。(クラスの中身の説明は省略します)
「//平日」の部分を以下のように書き換えます。

//祝日チェックし、平日なら白、祝日ならピンクにする。
if (HolidayChecker.Holiday(dt_Now.AddDays(count)).holiday == HolidayChecker.HolidayInfo.HOLIDAY.WEEKDAY) 
{
    b.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 255, 255, 255));

}else{
    b.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 247, 223, 223));
}
break;

これで祝日も表示されるようになりました。
WPAC10

横画面だとこんな感じ。ちゃんとローテートしても調整されます。XAML素晴らしい。
WPAC11

如何だったでしょうか?
応用すれば自作カレンダーコントロールとかも作れると思います。

今回のプロジェクトのソースはこちら→Calendar
「HolidayChecker.cs」クラスはこちら→HolidayChecker

来年こそ日本でWindowsPhone8で出ることを願っていますw
ではではー。

One thought on “WindowsPhoneでスケジュール用カレンダー(月表示)を作ってみる。”

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください