XamDateTimeEditor で表示されるカレンダーの特定日付の背景色および文字色をカスタマイズ方法をご紹介します。

実装方法

XamDateTimeEditor のカレンダー部分の日付コントロールは CalendarDay コントロールにより、表現しています。

土曜、日曜の表現方法をカスタマイズするために、CalendarDay の背景色(Background)および文字色(Foreground)を設定します。

また、特定日付の指定は、ConverterParameterプロパティにカンマ区切りで日付情報を設定しています。

<igEditors:XamDateTimeEditor Margin="10" >
    <igEditors:XamDateTimeEditor.Resources>
        <Style TargetType="{x:Type igEditors:XamMonthCalendar}">
            <EventSetter Event="ExecutedCommand" Handler="XamMonthCalendar_ExecutedCommand"/>
        </Style>
        <Style TargetType="{x:Type igEditors:CalendarDay}">
            <!-- 特定日の背景色を変更するコンバーター -->
            <Setter Property="Background" 
                    Value="{Binding RelativeSource={RelativeSource Self},
                    Converter={StaticResource HolidayToBackgroundConverter},
                    ConverterParameter='2019/10/14,2019/10/22'}" />
            <!-- 特定日の文字色を変更するコンバーター -->
            <Setter Property="Foreground" 
                    Value="{Binding RelativeSource={RelativeSource Self},
                    Converter={StaticResource HolidayToForegroundConverter},
                    ConverterParameter='2019/10/14,2019/10/22'}" />
        </Style>
    </igEditors:XamDateTimeEditor.Resources>
</igEditors:XamDateTimeEditor>

また、特定日付の、コンバーターにて判定を行います。 下記例では、特定日付および土曜、日曜の背景色を変更しています。

/// <summary>
/// カレンダー日付から特定日付の背景色を変換するコンバーター
/// </summary>
public class HolidayToBackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // 特定日付の情報を取得
        if (parameter != null && !string.IsNullOrEmpty(parameter.ToString()))
        {
            string[] holidays = parameter.ToString().Split(',');
            foreach(string holidayStr in holidays)
            {
                DateTime holiday = DateTime.Parse(holidayStr);
                if((value as CalendarDay).StartDate.Date.ToString("yyyy/MM/dd") == holiday.ToString("yyyy/MM/dd"))
                {
                    return Brushes.Orange;
                }
            }

        }
        // 土曜
        if ((value as CalendarDay).StartDate.DayOfWeek == DayOfWeek.Saturday)
        {
            return Brushes.Blue;
        }
        // 日曜
        else if ((value as CalendarDay).StartDate.DayOfWeek == DayOfWeek.Sunday)
        {
            return Brushes.Red;
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

文字色も同様にコンバーターを作成します。

/// <summary>
/// カレンダー日付から特定日付の文字色を変換するコンバーター
/// </summary>
public class HolidayToForegroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // 特定日付の情報を取得
        if (parameter != null && !string.IsNullOrEmpty(parameter.ToString()))
        {
            string[] holidays = parameter.ToString().Split(',');
            foreach (string holidayStr in holidays)
            {
                DateTime holiday = DateTime.Parse(holidayStr);
                if ((value as CalendarDay).StartDate.Date.ToString("yyyy/MM/dd") == holiday.ToString("yyyy/MM/dd"))
                {
                    return Brushes.White;
                }
            }

        }
        // 土曜
        if ((value as CalendarDay).StartDate.DayOfWeek == DayOfWeek.Saturday)
        {
            return Brushes.White;
        }
        // 日曜
        else if ((value as CalendarDay).StartDate.DayOfWeek == DayOfWeek.Sunday)
        {
            return Brushes.White;
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

また、カレンダーを前月、次月を選択した場合に描画をリフレッシュするために下記の処理を入れ込みます。

<Style TargetType="{x:Type igEditors:XamMonthCalendar}">
    <EventSetter Event="ExecutedCommand" Handler="XamMonthCalendar_ExecutedCommand"/>
</Style>
private void XamMonthCalendar_ExecutedCommand(object sender, Infragistics.Windows.Controls.Events.ExecutedCommandEventArgs e)
{
    XamMonthCalendar xamMonthCalendar = sender as XamMonthCalendar;
    xamMonthCalendar.Dispatcher.BeginInvoke(new Action(() =>
    {
        DependencyObject fobj =
             Infragistics.Windows.Utilities.GetDescendantFromType<CalendarDay>(
             xamMonthCalendar,
             true,
             (calDay) =>
             {
                 BindingExpression bg = calDay.GetBindingExpression(CalendarDay.BackgroundProperty);
                 if (bg != null)
                 {
                     bg.UpdateTarget();
                 }
                 BindingExpression fg = calDay.GetBindingExpression(CalendarDay.ForegroundProperty);
                 if (fg != null)
                 {
                     fg.UpdateTarget();
                 }
                 return false;
             });
    }),DispatcherPriority.Background);

}

製品について

Ultimate UI for WPF