WPF:将DateTime类型的viewmodel属性绑定到ItemsControl中的Calendar

时间:2011-02-18 13:12:26

标签: wpf datetime calendar itemscontrol

我遇到WPF绑定问题。我想将Months列表绑定到ItemsControl,每个月显示一个Calendar Control。但每个呈现的日历显示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

为什么会这样?

编辑:提供<Calendar DisplayDate="{Binding CurrentDate, Mode=OneWay}" />时绑定有效。

4 个答案:

答案 0 :(得分:14)

这是否符合您的需求?

<Calendar SelectedDate="{Binding Path=CurrentDate}"
          DisplayDate="{Binding Path=SelectedDate,
                                RelativeSource={RelativeSource Self}, 
                                Mode=OneWay}" />

答案 1 :(得分:4)

问题似乎是Calendar如何初始化DisplayDate属性。它目前是这样的:

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

即使在建立绑定之前初始化DisplayDate,它仍然会被推回到绑定源,就像之后设置一样。这很可能是一个错误。

您可以使用以下内容解决此问题:

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

或者您可以使用事件处理程序或附加行为在以后建立绑定(即加载日历时)。

答案 2 :(得分:1)

尝试绑定到SelectedDate而不是DisplayDate。或者,如果您设置IsTodayHighlighted =“false”,请查看它是否更有效。

答案 3 :(得分:0)

我确实在某处读过如果将列表框绑定到一组选定项目(例如来自另一个列表框),它只会在第二个列表框中显示所选的第一个选定项目。我不确定这是否与此相关,但它看起来可能是。