我已经创建了一个基于Calendar的自定义控件,它也实现了。它的功能是它可以根据Observable Collection中是否存在该日来对代码天进行着色。
我为日历的CalendarDayButton组件创建了一个模板(通过复制日历源代码),其中我添加了一个矩形,可用于显示背景颜色。矩形填充属性通过多重绑定和使用转换器绑定到我的DataContext和我的自定义日历。
当CalendarDayButton的DataContext发生更改时,这很有效,但它似乎完全忽略了对我的observable集合所做的所有更改。这意味着,当我添加或删除一天时,日历不会更新它的外观。我在转换器Convert函数中有一个断点。它会在日历加载时调用,但不会在我添加日期时调用。
我还在我的日历的OnPropertyChanged函数中创建了一个断点,它的PropertyChanged总是为null。我还尝试将我的ObservableCollection转换为DependencyProperty,并使用单个Bindings对象。没变。看起来像矩形的绑定事件并没有创建一个监听器。
现在我将日历的日期更改为DateTime.Min然后再返回,这会导致每个按钮的数据上下文更新为解决此问题,但这很难看。
这是我的自定义日历:
namespace Lekstuga
{
public class ColouredCalendar : Calendar, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public DependencyProperty DoneMarkedDaysProperty =
DependencyProperty.Register("DoneMarkedDaysAttribute", typeof (ObservableCollection<DateTime>),
typeof (ColouredCalendar));
public ObservableCollection<DateTime> DoneMarkedDaysAttribute
{
get { return (ObservableCollection<DateTime>) GetValue(DoneMarkedDaysProperty); }
set { SetValue(DoneMarkedDaysProperty, value); }
}
static ColouredCalendar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColouredCalendar), new FrameworkPropertyMetadata(typeof(ColouredCalendar)));
}
public ColouredCalendar()
: base()
{
SetValue(DoneMarkedDaysProperty, new ObservableCollection<DateTime>());
DoneMarkedDaysAttribute.Add(new DateTime(2013, 05, 01));
DoneMarkedDaysAttribute.Add(new DateTime(2013, 05, 02));
DoneMarkedDaysAttribute.Add(new DateTime(2013, 05, 03));
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public void AddNextDay()
{
var greenDays = DoneMarkedDaysAttribute;
var nextDay = greenDays[greenDays.Count - 1].AddDays(1.0d);
DoneMarkedDaysAttribute.Add(nextDay);
OnPropertyChanged("DoneMarkedDaysAttribute");
}
public void Refresh()
{
var curDate = DisplayDate;
DisplayDate = DateTime.MinValue;
DisplayDate = curDate;
}
}
}
这是我的转换器:
namespace Lekstuga
{
class DayToColorConverter : IMultiValueConverter
{
private SolidColorBrush myGreenBrush = new SolidColorBrush(Colors.Green);
private SolidColorBrush myIndigoBrush = new SolidColorBrush(Colors.Indigo);
public DayToColorConverter()
{
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var tmp = (values[0] == null);
if (tmp == false)
{
tmp = (values[1] == null);
}
if (tmp == true) return null;
var day = ((DateTime) values[1]).Date;
var markedDays = (ObservableCollection<DateTime>)values[0];
if ( markedDays.Contains(day) )
{
return myGreenBrush;
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
最后我的CalendarDayButton模板的相关部分:
...
<Rectangle x:Name="TodayBackground" RadiusX="1" RadiusY="1" Opacity="0" Fill="#89B8FF"/>
<Rectangle x:Name="SelectedBackground" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}"/>
<Rectangle x:Name="Background" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}"/>
<Rectangle x:Name="DoneMarkingBackground" IsHitTestVisible="False" Visibility="Visible" >
<Rectangle.Fill>
<Binding Converter="{StaticResource DayToColorConv}" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:ColouredCalendar}}" Mode="OneWay" />
</Rectangle.Fill>
</Rectangle>
<ContentPresenter
x:Name="NormalText"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="5,1,5,1">
<TextElement.Foreground>
<SolidColorBrush x:Name="selectedText" Color="#FF333333"/>
</TextElement.Foreground>
</ContentPresenter>
<Path x:Name="Blackout" Opacity="0" Margin="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.5" Fill="#FF000000" Stretch="Fill" 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"/>
<Rectangle x:Name="DayButtonFocusVisual" Visibility="Collapsed" IsHitTestVisible="false" RadiusX="1" RadiusY="1" Stroke="#FF45D6FA"/>
...