QA@IT

C#でWPFを利用し、カレンダーを作成しようとしています。わからないことがあるのでお願いします。

8618 PV

WPFでカレンダーを作成しようと思い、こちらのホームページを内容を参考にさせていただきました。

http://blogs.wankuma.com/kazuki/archive/2008/01/20/118336.aspx

といってもそのまま利用させていただいてます。

//DateTimeConverter.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Globalization;
namespace WpfCalendar
{
    public class DateTimeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DateTime date = (DateTime)value;

            var days = (from day in Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month))
                        select new DateTime(date.Year, date.Month, day)).ToList();
            var first = days.First();
            for (int i = 0; i < (int)first.DayOfWeek; i++)
            {
                days.Insert(0, days.First().AddDays(-1));
            }

            var last = days.Last();
            for (int i = 0; i < 6 - (int)last.DayOfWeek; i++)
            {
                days.Add(days.Last().AddDays(1));
            }

            return days;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }  
}
//XAML
<Window x:Class="WpfCalendar.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox Name="calendar">
            <ListBox.ItemsSource>
                <Binding>
                    <Binding.Converter>
                        <c:DateTimeConverter xmlns:c="clr-namespace:WpfCalendar" />
                    </Binding.Converter>
                </Binding>
            </ListBox.ItemsSource>
            <ListBox.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="TextAlignment" Value="Right" />
                </Style>
            </ListBox.Resources>
            <ListBox.Template>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <StackPanel>
                        <UniformGrid Columns="7">
                            <TextBlock Text="日" />
                            <TextBlock Text="月" />
                            <TextBlock Text="火" />
                            <TextBlock Text="水" />
                            <TextBlock Text="木" />
                            <TextBlock Text="金" />
                            <TextBlock Text="土" />
                        </UniformGrid>
                        <UniformGrid Columns="7" IsItemsHost="True">
                        </UniformGrid>
                    </StackPanel>
                </ControlTemplate>
            </ListBox.Template>
        </ListBox>
    </Grid>
</Window>

これを実行すると、DateTimeConverter.csの
DateTime date = (DateTime)value;
でNullReferenceExceptionはハンドルされませんでした。と表示されます。(DateTime)valueがnullなのでこのようなエラーがでる
と思います。また、、WPFに2014/08/01〜2014/0831が表示されるので、NullReferenceExceptionのエラーはでないはずではと思うのでよくわかりません。どうか教えてくださいお願いします。

回答

DataContextに何も設定していないためです。

簡単に言えば、カレンダーに指定された基準日をもとにカレンダーを作るのに、その基準日を渡していません。

MainWindowのコンストラクタのInitializeComponentの下に

calendar.DataContext = DateTime.Today;

と追加すれば動くと思います。


または、xamlの方で直したければ例えば<grid>の下の行の<ListBox x:Name="calendar">を以下の様にすれば良いと思います。
(この場合先のcalendar.DataContext = DateTime.Today;は必要ありません)

        <ListBox x:Name="calendar" DataContext="{Binding Source={x:Static System:DateTime.Today}}">

なお、デザイン時にエラーになるのはその次の回で治してるみたいですね。

編集 履歴 (1)
  • ありがとうございます。できました。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。