I\'d like to bind a list of dates to the BlackoutDates property but it doesn\'t really seem to possible. Especially in a MVVM scenario. Has anyone accomplished something l
Here is an improved version of Matt's answer that allows us to work with the BlackoutDates as with any normal Observable collection (you don't need to create new collections each time you want to change the BlackoutDates). We store a list of all the calendars and datepickers binded and inside their tag we store the collection used in MVVM. An easy modification of the class will allow to work with ObservableCollection
// Adds a collection of command bindings to a date picker's existing BlackoutDates collection, since the collections are immutable and can't be bound to otherwise.
// Usage:
public class CalendarAttachedProperties : DependencyObject
{
#region Attributes
private static readonly List _calendars = new List();
private static readonly List _datePickers = new List();
#endregion
#region Dependency Properties
public static DependencyProperty RegisterBlackoutDatesProperty = DependencyProperty.RegisterAttached("RegisterBlackoutDates", typeof(CalendarBlackoutDatesCollection), typeof(CalendarAttachedProperties), new PropertyMetadata(null, OnRegisterCommandBindingChanged));
public static void SetRegisterBlackoutDates(DependencyObject d, CalendarBlackoutDatesCollection value)
{
d.SetValue(RegisterBlackoutDatesProperty, value);
}
public static CalendarBlackoutDatesCollection GetRegisterBlackoutDates(DependencyObject d)
{
return (CalendarBlackoutDatesCollection)d.GetValue(RegisterBlackoutDatesProperty);
}
#endregion
#region Event Handlers
private static void CalendarBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
CalendarBlackoutDatesCollection blackoutDates = sender as CalendarBlackoutDatesCollection;
Calendar calendar = _calendars.First(c => c.Tag == blackoutDates);
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (CalendarDateRange dateRange in e.NewItems)
{
calendar.BlackoutDates.Add(dateRange);
}
}
}
private static void DatePickerBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
CalendarBlackoutDatesCollection blackoutDates = sender as CalendarBlackoutDatesCollection;
DatePicker datePicker = _datePickers.First(c => c.Tag == blackoutDates);
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (CalendarDateRange dateRange in e.NewItems)
{
datePicker.BlackoutDates.Add(dateRange);
}
}
}
#endregion
#region Private Methods
private static void OnRegisterCommandBindingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
Calendar calendar = sender as Calendar;
if (calendar != null)
{
CalendarBlackoutDatesCollection bindings = e.NewValue as CalendarBlackoutDatesCollection;
if (bindings != null)
{
if (!_calendars.Contains(calendar))
{
calendar.Tag = bindings;
_calendars.Add(calendar);
}
calendar.BlackoutDates.Clear();
foreach (var dateRange in bindings)
{
calendar.BlackoutDates.Add(dateRange);
}
bindings.CollectionChanged += CalendarBindings_CollectionChanged;
}
}
else
{
DatePicker datePicker = sender as DatePicker;
if (datePicker != null)
{
CalendarBlackoutDatesCollection bindings = e.NewValue as CalendarBlackoutDatesCollection;
if (bindings != null)
{
if (!_datePickers.Contains(datePicker))
{
datePicker.Tag = bindings;
_datePickers.Add(datePicker);
}
datePicker.BlackoutDates.Clear();
foreach (var dateRange in bindings)
{
datePicker.BlackoutDates.Add(dateRange);
}
bindings.CollectionChanged += DatePickerBindings_CollectionChanged;
}
}
}
}
#endregion
}
Here is the ObservableCollection
// Adds a collection of command bindings to a date picker's existing BlackoutDates collection, since the collections are immutable and can't be bound to otherwise.
// Usage:
public class CalendarAttachedProperties : DependencyObject
{
#region Attributes
private static readonly List _calendars = new List();
private static readonly List _datePickers = new List();
#endregion
#region Dependency Properties
public static DependencyProperty RegisterBlackoutDatesProperty = DependencyProperty.RegisterAttached("RegisterBlackoutDates", typeof(ObservableCollection), typeof(CalendarAttachedProperties), new PropertyMetadata(null, OnRegisterCommandBindingChanged));
public static void SetRegisterBlackoutDates(DependencyObject d, ObservableCollection value)
{
d.SetValue(RegisterBlackoutDatesProperty, value);
}
public static ObservableCollection GetRegisterBlackoutDates(DependencyObject d)
{
return (ObservableCollection)d.GetValue(RegisterBlackoutDatesProperty);
}
#endregion
#region Event Handlers
private static void CalendarBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ObservableCollection blackoutDates = sender as ObservableCollection;
Calendar calendar = _calendars.First(c => c.Tag == blackoutDates);
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (DateTime date in e.NewItems)
{
calendar.BlackoutDates.Add(new CalendarDateRange(date));
}
}
}
private static void DatePickerBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ObservableCollection blackoutDates = sender as ObservableCollection;
DatePicker datePicker = _datePickers.First(c => c.Tag == blackoutDates);
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (DateTime date in e.NewItems)
{
datePicker.BlackoutDates.Add(new CalendarDateRange(date));
}
}
}
#endregion
#region Private Methods
private static void OnRegisterCommandBindingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
Calendar calendar = sender as Calendar;
if (calendar != null)
{
ObservableCollection bindings = e.NewValue as ObservableCollection;
if (bindings != null)
{
if (!_calendars.Contains(calendar))
{
calendar.Tag = bindings;
_calendars.Add(calendar);
}
calendar.BlackoutDates.Clear();
foreach (DateTime date in bindings)
{
calendar.BlackoutDates.Add(new CalendarDateRange(date));
}
bindings.CollectionChanged += CalendarBindings_CollectionChanged;
}
}
else
{
DatePicker datePicker = sender as DatePicker;
if (datePicker != null)
{
ObservableCollection bindings = e.NewValue as ObservableCollection;
if (bindings != null)
{
if (!_datePickers.Contains(datePicker))
{
datePicker.Tag = bindings;
_datePickers.Add(datePicker);
}
datePicker.BlackoutDates.Clear();
foreach (DateTime date in bindings)
{
datePicker.BlackoutDates.Add(new CalendarDateRange(date));
}
bindings.CollectionChanged += DatePickerBindings_CollectionChanged;
}
}
}
}
#endregion
}