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]);
}
}
目前有个问题,高亮日期的设置总是滞后于日期刷新的动作,所以代码里面 是向前和向后 额外多加了一个月的信息(主动刷新我感觉也不太合适)。不知道各位有没有什么好的方法。
源码下载:
http://download.csdn.net/download/bornonew/10244234