Wpf 日历控件,单击可更改一天的背景颜色

Wpf 日历控件,单击可更改一天的背景颜色,wpf,Wpf,我有一个扩展日历控件,它绑定到一个包含日期和状态值的类。这个想法本质上是区分国定假日、国定假日和个人休假日。我使用转换器以不同的颜色呈现这些内容,该转换器根据与日历控件关联的对象列表检查当前日期,以选择日历日中某个元素的填充颜色。这一切都很完美 问题是,我想支持当用户单击某一天(在给定模式下)时,他们可以选择或取消选择该日期作为休息日/假日。使用PreviewMouseDown,我根据所选数据上下文(datetime)选择对象并更新其状态。这很好,但是我无法让calendar控件执行刷新 cal

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

问题是,我想支持当用户单击某一天(在给定模式下)时,他们可以选择或取消选择该日期作为休息日/假日。使用PreviewMouseDown,我根据所选数据上下文(datetime)选择对象并更新其状态。这很好,但是我无法让calendar控件执行刷新

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


我尝试过UpdateLayout()和其他方法。我不知道这是否是一个问题,因为我正在尝试从鼠标事件中重新渲染。你知道如何重新绘制日历控件以便启动转换器吗?

终于找到了。为繁荣发帖,以防其他人也试图做类似的事情

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

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

    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);

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

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


这是多么彻底的痛苦啊。

好吧,我想我在这方面取得了一些进展,但还不是100%。如果我添加这个:var test=visualtreeheloper.GetChild(visualtreeheloper.GetParent(e.OriginalSource作为DependencyObject),1)作为矩形;test.Fill=新的SolidColorBrush(Colors.Red)。。。单击某一天时,我可以更改日历日内元素的填充。我希望这将启动一个布局,转换器将覆盖设置。不幸的是,它似乎已经覆盖了模板颜色。(每个月的这一天都是红色的。)