WPF: привязка свойства viewmodel типа DateTime к календарю внутри ItemsControl - PullRequest
11 голосов
/ 18 февраля 2011

У меня проблема с привязкой 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>

** Место, где коллекция назначена для ItemSource **

        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 :

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}" /> привязка работает.

Ответы [ 4 ]

14 голосов
/ 05 апреля 2011

Это соответствует вашим потребностям?

<Calendar SelectedDate="{Binding Path=CurrentDate}"
          DisplayDate="{Binding Path=SelectedDate,
                                RelativeSource={RelativeSource Self}, 
                                Mode=OneWay}" />
4 голосов
/ 06 апреля 2011

Проблема заключается в том, как Calendar инициализирует свойство DisplayDate. В настоящее время это происходит так:

public Calendar() {
    // ...
    base.SetCurrentValueInternal(DisplayDateProperty, DateTime.Today);
}

Похоже, что даже несмотря на то, что DisplayDate инициализируется до установления привязки, он все равно будет возвращаться к источнику привязки, как если бы он был установлен после. Скорее всего, это ошибка.

Вы можете обойти это, используя что-то вроде:

public class MyCalendar : Calendar {
    public MyCalendar() {
        this.ClearValue(DisplayDateProperty);
    }
}

Или вы можете установить привязку позднее (т. Е. При загрузке Календаря), используя обработчик событий или прикрепленное поведение.

1 голос
/ 20 февраля 2011

Попробуйте связать с SelectedDate вместо DisplayDate.В качестве альтернативы, посмотрите, работает ли он лучше, если вы установите IsTodayHighlighted = "false".

0 голосов
/ 04 апреля 2011

Я где-то читал, что если вы связываете список со множеством выбранных элементов (например, из другого списка), он показывает только первый выбранный элемент, выбранный во втором списке. Я не уверен, что это уместно здесь, но похоже, что это может быть.

...