原始用例:
这是我试图解决的一个可能的用例:
预期:日历显示现在的日期
实际:(仅对SelectedDate进行绑定)日历仅移动其选定日期,但会一直显示之前选择的月份
我的解决方案:
在MVVM场景中,我显示了一个Calendar
控件,其SelectedDate与我的ViewModel中的SelectedDate
属性绑定。我的VM中的属性在设置时触发它的PropertyChanged
事件。
我的VM中的所选日期也可以从我的代码中的其他部分设置,因此我希望我的日历始终显示所选日期(例如,当另一个月设置为所选日期时,我希望我的日历切换到那个月)。为了得到这种行为,我还将我的日历的DisplayDate
属性绑定到我的SelectedDate属性,这给了我预期的行为,除非我点击上个月或下个月的灰色日期。
这是我在XAML中的日历:
<Calendar SelectedDate="{Binding Path=SelectedDate}" DisplayDate="{Binding Path=SelectedDate}" />
这是我的ViewModel中的SelectedDate
属性(实现INotifyPropertyChanged
)
public DateTime SelectedDate
{
get
{
return selectedDate;
}
set
{
selectedDate = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("SelectedDate"));
}
}
解决方案的问题:
显然点击灰色日期会导致鼠标按下SelectedDate
,鼠标按下时再次设置,这会导致选择两个月后的日期。
有没有更好的方法来实现这种行为?或者我可以修复DisplayDate问题(没有太多的黑客攻击,意味着代码背后没有/尽可能少的代码)?
我真正想要的是SelecteDate
属性,它也具有DisplayDate
属性的行为:)
感谢您的帮助!
答案 0 :(得分:4)
我刚刚遇到这个问题并偶然发现了这个问题,虽然它有效但我进一步解构并发现解决方案非常简单。只需将DisplayDate
绑定为Mode=OneTime
即可。不需要任何其他东西。
DisplayDate="{Binding SelectedDate, Mode=OneTime, UpdateSourceTrigger=PropertyChanged}"
SelectedDate="{Binding SelectedDate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
答案 1 :(得分:3)
我现在已经决定修复它的方式是在我的代码后面,在日历的加载事件上:
private void CalendarLoaded(object sender, RoutedEventArgs e)
{
if (this.ViewStartCalendar.SelectedDate.HasValue)
{
this.ViewStartCalendar.DisplayDate = this.ViewStartCalendar.SelectedDate.Value;
}
}
我宁愿在XAML或我的viewmodel中完成它,但我可以使用这个解决方案。