WPF: свойство привязки viewmodel типа DateTime к календарю внутри ItemsControl
У меня проблема с привязкой WPF. Я хочу связать список месяцев с элементом ItemsControl, который показывает элемент управления календарем для каждого месяца. Но каждый отображаемый календарь показывает DateTime.Now, а не связанные DateTimes. Кто-нибудь знает, почему это происходит?
Это то, что я до сих пор:
MainWindow.xaml
<Window x:Class="CalendarListTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ItemsControl x:Name="calendarList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Calendar DisplayDate="{Binding CurrentDate}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
** Место, где коллекция присваивается ItemsSource **
private void Window_Loaded( object sender, RoutedEventArgs e )
{
CalendarList list = new CalendarList( );
list.Add( new CalendarMonth( ) { CurrentDate = DateTime.Parse( "1.1.1979" ) } );
list.Add( new CalendarMonth( ) { CurrentDate = DateTime.Parse( "1.2.1979" ) } );
list.Add( new CalendarMonth( ) { CurrentDate = DateTime.Parse( "1.3.1979" ) } );
calendarList.ItemsSource = list;
}
CalendarMonth ViewModel:
public class CalendarMonth
{
private DateTime _currentDate;
public DateTime CurrentDate
{
get { return _currentDate; }
set { _currentDate = value; }
}
}
И коллекция для привязки к ItemsControl:
public class CalendarList : ObservableCollection<CalendarMonth>
{
}
Теперь результат:
![enter image description here]()
Почему это происходит?
edit: При предоставлении <Calendar DisplayDate="{Binding CurrentDate, Mode=OneWay}" />
работает привязка.
Ответы
Ответ 1
Проблема связана с тем, как календарь инициализирует свойство DisplayDate. В настоящее время он выглядит так:
public Calendar() {
// ...
base.SetCurrentValueInternal(DisplayDateProperty, DateTime.Today);
}
Похоже, что несмотря на то, что DisplayDate инициализируется до установления привязки, он все равно будет возвращен в источник привязки, как если бы он был установлен после. Это, скорее всего, ошибка.
Вы можете обойти это, используя что-то вроде:
public class MyCalendar : Calendar {
public MyCalendar() {
this.ClearValue(DisplayDateProperty);
}
}
Или вы можете установить привязку позднее (например, при загрузке календаря) с помощью обработчика событий или приложенного поведения.
Ответ 2
Соответствует ли это вашим потребностям?
<Calendar SelectedDate="{Binding Path=CurrentDate}"
DisplayDate="{Binding Path=SelectedDate,
RelativeSource={RelativeSource Self},
Mode=OneWay}" />
Ответ 3
Попробуйте привязку к SelectedDate вместо DisplayDate. Кроме того, посмотрите, работает ли он лучше, если вы установите IsTodayHighlighted = "false".
Ответ 4
Я где-то читал, что если вы привязываете список к набору выбранных элементов (например, из другого списка), он отображает только первый выбранный элемент, выбранный во втором списке. Я не уверен, что это актуально здесь, но похоже, что это возможно.