日历控件,单击时更改日背景颜色

时间:2010-08-18 01:46:25

标签: wpf

我有一个扩展的Calendar控件,它绑定到包含日期和状态值的类。这个想法基本上区分了国家法定假日,州假日和个人休假。我使用转换器以不同颜色渲染这些颜色,该转换器根据与日历控件关联的对象列表检查当前日期,以便为CalendarDay中的元素选择填充颜色。这一切都很完美。

问题是,我想支持当用户点击一天(在给定模式下)时,他们可以选择或取消选择该日期作为休假日。使用PreviewMouseDown我按所选数据上下文(datetime)选择对象并更新它的状态。这工作正常,但我无法让日历控件执行刷新。

日历没有绑定到我的自定义类,我不确定CalendarDay是如何绑定的,但它似乎只有一个指向DateTime值的数据上下文。所以NotifyPropertyChanged已经出局了。如果我点击日期并切换月份并返回日期会按预期突出显示,我需要的是告诉日历重新绘制。我一直在寻找强迫重绘的例子,到目前为止还没有任何工作。

我尝试过UpdateLayout()等等。我不知道这是否是一个问题,因为我正试图从鼠标事件中重新渲染。有关如何重新绘制日历控件以便启动转换器的任何想法吗?

1 个答案:

答案 0 :(得分:3)

终于找到了。如果其他人一直试图做类似的事情,那就要发财。

正如评论中所提到的,设置元素的填充颜色确实会改变背景颜色,但在所有月份都会这样做。这实际上是有道理的,因为填充通常由模板管理并基于绑定和转换器进行设置。

解决方案是在单击日期时重置鼠标按下事件的绑定。 这是事件代码:

    protected override void OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
    {
        if (!(e.OriginalSource is FrameworkElement &&
            (e.OriginalSource as FrameworkElement).DataContext is DateTime))
        {
            base.OnPreviewMouseLeftButtonDown(e);
            return;
        }

        DateTime dateTime = (DateTime)(e.OriginalSource as FrameworkElement).DataContext;

        var calendarDay = _calendarDays.Single(d => d.CalendarDate == dateTime);

        if (calendarDay.IsHoliday)
        {
            calendarDay.CalendarKey = null;
        }
        else
        {
            calendarDay.CalendarKey = Guid.NewGuid();
        }
        var holidayBackgroundRect = VisualTreeHelper.GetChild(VisualTreeHelper.GetParent(e.OriginalSource as DependencyObject), 1) as Rectangle;
        var binding = new MultiBinding();
        binding.Bindings.Add(new Binding());
        binding.Bindings.Add(new Binding() { ElementName = "Calendar" });
        binding.Converter = new CalendarDayColorConverter();
        holidayBackgroundRect.SetBinding(Rectangle.FillProperty, binding);
        base.OnPreviewMouseLeftButtonDown(e);

    }

转换器决定了当天的颜色。它接受日历中的当前绑定日期,以及日历控件本身,它可以检索当前的holidayDays列表。

通过重新指定绑定,它会强制日历日刷新该日期。

多么痛苦。