wpf Calendar控件 日期高亮显示

戎永福
2023-12-01

1对某些特殊日期进行高亮显示

2解决鼠标移动到日期控件内,需点击两次外部才能将焦点移出的问题

如果要高亮显示的日期是变化的,可以参考以下方法。

首先要设置一下Calendar的CalendarDayButtonStyle,加入一个高亮显示的框(HaveHistoryBackground)。将其显示绑定到一个list里面,如果日期在list里面,则显示,不在则不显示。

       <Calendar.CalendarDayButtonStyle>
                <Style   TargetType="{x:Type CalendarDayButton}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type CalendarDayButton}">
                                <ControlTemplate.Resources>
                                    <local:CalendarConverter x:Key="calendarConverter" />
                                </ControlTemplate.Resources>
                                <Grid>
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition GeneratedDuration="0:0:0.1"/>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="Normal"/>
                                            <VisualState x:Name="MouseOver">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Pressed">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Disabled">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
                                                    <DoubleAnimation Duration="0" To=".35" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="NormalText"/>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="SelectionStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition GeneratedDuration="0"/>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="Unselected"/>
                                            <VisualState x:Name="Selected">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To=".75" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SelectedBackground"/>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="CalendarButtonFocusStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition GeneratedDuration="0"/>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="CalendarButtonFocused">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DayButtonFocusVisual">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <Visibility>Visible</Visibility>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="CalendarButtonUnfocused">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DayButtonFocusVisual">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <Visibility>Collapsed</Visibility>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="ActiveStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition GeneratedDuration="0"/>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="Active"/>
                                            <VisualState x:Name="Inactive">
                                                <Storyboard>
                                                    <ColorAnimation Duration="0" To="#FF777777" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="NormalText"/>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="DayStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition GeneratedDuration="0"/>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="RegularDay"/>
                                            <VisualState x:Name="Today">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TodayBackground"/>
                                                    <ColorAnimation Duration="0" To="#FFFFFFFF" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="NormalText"/>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="BlackoutDayStates">
                                            <VisualStateGroup.Transitions>
                                                <VisualTransition GeneratedDuration="0"/>
                                            </VisualStateGroup.Transitions>
                                            <VisualState x:Name="NormalDay"/>
                                            <VisualState x:Name="BlackoutDay">
                                                <Storyboard>
                                                    <DoubleAnimation Duration="0" To=".2" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Blackout"/>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <Rectangle x:Name="TodayBackground" Fill="#FFAAAAAA" Opacity="0" RadiusY="1" RadiusX="1"/>
                                    <Rectangle x:Name="SelectedBackground" Fill="Yellow" Opacity="0" RadiusY="1" RadiusX="1"/>
                                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
                                    <Rectangle x:Name="HighlightBackground" Fill="#FFBADDE9" Opacity="0" RadiusY="1" RadiusX="1"/>
                                    <ContentPresenter x:Name="NormalText" TextElement.Foreground="#FF333333" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="5,1,5,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    <Path x:Name="Blackout" Data="M8.1772461,11.029181 L10.433105,11.029181 L11.700684,12.801641 L12.973633,11.029181 L15.191895,11.029181 L12.844727,13.999395 L15.21875,17.060919 L12.962891,17.060919 L11.673828,15.256231 L10.352539,17.060919 L8.1396484,17.060919 L10.519043,14.042364 z" Fill="#FF000000" HorizontalAlignment="Stretch" Margin="3" Opacity="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" VerticalAlignment="Stretch"/>
                                    <Rectangle x:Name="DayButtonFocusVisual" IsHitTestVisible="false" RadiusY="1" RadiusX="1" Stroke="#FF45D6FA" Visibility="Collapsed"/>
                                    <Rectangle x:Name="HaveHistoryBackground" IsHitTestVisible="False" Fill="Red" Opacity="0.5"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <DataTrigger Binding="{Binding Converter={StaticResource calendarConverter}}"  Value="{x:Null}">
                                        <Setter TargetName="HaveHistoryBackground" Property="Visibility" Value="Hidden" />
                                    </DataTrigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>


                        </Setter.Value>
                    </Setter>
                </Style>
            </Calendar.CalendarDayButtonStyle>
calendarconverter类如下

   public class CalendarConverter : IValueConverter
    {
        public static List<DateTime> dict = new List<DateTime>();

        static CalendarConverter()
        {

        }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string text = null;
            for (int i = 0; i < dict.Count; i++)
            {
                if (dict[i] == (DateTime)value)
                {
                    text = "HaveHistory";
                }
            }

            return text;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

        public static void Update(List<DateTime> MIList)
        {
            dict.Clear();
            dict = MIList;
        }
    }
后台代码如下
   public MainWindow()
        {
            RefreshData(DateTime.Now);
            InitializeComponent();
            //设置不可选的日期
            myCalender.BlackoutDates.Add(new CalendarDateRange(DateTime.Now.AddDays(1), DateTime.Now.AddDays(1)));
        }

        private DateTime oldDisplayDate = new DateTime(1970, 1, 1);

        private void myCalender_DisplayDateChanged(object sender, CalendarDateChangedEventArgs e)
        {
            if (oldDisplayDate.Year == myCalender.DisplayDate.Year && oldDisplayDate.Month == myCalender.DisplayDate.Month)
            {
                return;
            }
            else
            {
                oldDisplayDate = myCalender.DisplayDate;
                RefreshData(myCalender.DisplayDate);
            }
        }


        private void RefreshData(DateTime displayDate)
        {
            displayDate = new DateTime(displayDate.Year, displayDate.Month, 1);
            DateTime dateTime1 = displayDate.AddMonths(2);
            DateTime dateTime2 = displayDate.AddMonths(-1);
            List<DateTime> dateList = new List<DateTime>();
            dateList.Add(dateTime2);
            dateList.Add(dateTime2.AddMonths(1).AddDays(-1));
            dateList.Add(dateTime2.AddMonths(1));
            dateList.Add(dateTime2.AddMonths(2).AddDays(-1));
            dateList.Add(dateTime2.AddMonths(2));
            dateList.Add(dateTime2.AddMinutes(3).AddDays(-1));
            CalendarConverter.Update(dateList);
        }

        private void myCalender_PreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            if (Mouse.Captured is System.Windows.Controls.Primitives.CalendarItem)
            {
                Mouse.Capture(null);
            }
        }

        private void myCalender_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            if (myCalender.SelectedDates != null && myCalender.SelectedDates.Count > 0)
            {
                //选中某一天的操作
                Console.WriteLine(myCalender.SelectedDates[0]);
            }
        }

PreviewMouserUp事件是为了将焦点及时移出Calendar。避免两次点击,才能将焦点移出。

目前有个问题,高亮日期的设置总是滞后于日期刷新的动作,所以代码里面 是向前和向后 额外多加了一个月的信息(主动刷新我感觉也不太合适)。不知道各位有没有什么好的方法。

源码下载:

http://download.csdn.net/download/bornonew/10244234




 类似资料: