2010-08-18 1 views
1

У меня есть расширенный элемент управления календарем, связанный с классом, содержащим значения даты и состояния. Идея состоит в том, чтобы различать национальные праздники, государственные праздники и личные выходные. Я представляю их в разных цветах с помощью конвертера, который проверяет текущую дату на список объектов, связанных с элементом управления календарем, чтобы выбрать цвет заливки для элемента в CalendarDay. Все это прекрасно работает.Управление календарем, изменение цвета фона дня при нажатии

Проблема в том, что я хочу поддерживать это, когда пользователь нажимает на день (в определенном режиме), они могут выбрать или отменить эту дату как выходной день/отпуск. используя PreviewMouseDown Я выбираю объект по выбранному контексту данных (datetime) и обновляю его состояние. Это прекрасно работает, однако я не могу заставить элемент управления календарем выполнить обновление.

Календарь не привязан к моему пользовательскому классу, я точно не знаю, как привязан к CalendarDay, но он, похоже, имеет контекст данных, указывающий на значение DateTime. Так NotifyPropertyChanged отсутствует. Если я нажимаю на дату и переключаю месяцы и назад, то дата отображается как ожидаемая, мне нужно, чтобы календарь переписывал. Я искал примеры для того, чтобы заставлять репайны, и до сих пор ничего не работало.

Я пробовал UpdateLayout() среди прочего. Я не знаю, является ли это проблемой, потому что я пытаюсь повторно выполнить рендеринг внутри события мыши. Любые идеи о том, как перерисовать календарный элемент управления, чтобы можно было отключить конвертер?

+0

Хорошо, я думаю, что я сделал некоторый прогресс в этом, но это еще не 100%. Если я добавлю это: var test = VisualTreeHelper.GetChild (VisualTreeHelper.GetParent (e.OriginalSource как DependencyObject), 1) как Rectangle; test.Fill = новый SolidColorBrush (Colors.Red); ... к событию mousedown при нажатии на день я могу изменить заполнение элемента в CalendarDay. Я надеялся, что это запустит макет, где конвертер переопределит настройку. К сожалению, он, похоже, переопределил цвет шаблона. (этот день краснеет каждый месяц). –

ответ

3

FINALLY нашел его. Проводка для процветания в случае, если другие пытаются сделать что-то подобное.

Как указано в комментарии, установка цвета заливки элемента изменила цвет фона, но сделала это в течение этого дня в течение всех месяцев. Это имело смысл на самом деле, потому что заполнение обычно управлялось шаблоном и устанавливалось на основе привязки и конвертера.

Решение заключалось в том, чтобы сбросить привязку при нажатии мыши при нажатии на дату. Это код события:

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

    } 

Преобразователь, что определяет цвет дня. он принимает текущую связанную дату из календаря и сам календарь, где он может получить текущий список праздничных дней.

Повторно указав привязку, он заставляет календарный день обновлять эту дату.

Какая полная боль.