TMonthCalendar 行为已更改
Posted
技术标签:
【中文标题】TMonthCalendar 行为已更改【英文标题】:TMonthCalendar behaviour changed 【发布时间】:2014-09-03 15:59:12 【问题描述】:在将我的一个 Win32 VCL 应用程序从 Delphi 2006 迁移到 delphi XE6 的过程中,我遇到了以下问题:
我的一个表单有一个 TMonthCalendar(插入 TPanel 以供记录),以帮助用户选择要在图表中查看的一周。每周我的意思是星期一是第一天,星期日是最后一天(法语语言环境)。为了实现这样的星期选择模式,我将 multiSelect 属性设置为 true 并将以下代码放入 CalendarClick 事件中:
MonthCalendar1.MultiSelect := True;
//Temporarily storing the selected day in a variable
TempoDate := MonthCalendar1.Date;
//searching for the monday right before the selected day (by user)
while dayOfWeek(TempoDate) <> 2 do
TempoDate := IncDay( TempoDate , -1 );
//Setting the monday as the start date of the selection
MonthCalendar1.Date := TempoDate;
//Setting the Sunday as the last day of selection
MonthCalendar1.EndDate := IncDay(tempoDate, 6);
这曾经在 Delphi 2006 上运行良好(在 win XP 计算机上编译)。 现在我已经将相同的代码移植到 Delphi XE6(在 win7 计算机上编译)我有以下问题:
单击右箭头 (>) 切换到下个月时,大多数情况下都会失败。当包含下个月 1 日的一周中的星期一仍在上个月时,它实际上会失败。例如:从 2014 年 9 月切换到 2014 年 10 月失败,因为 10 月 1 日之前的星期一是 9 月(9 月 29 日星期一)。 所以这让我回到了九月。 另一方面,从 8 月 14 日切换到 9 月 14 日是可行的,因为 9 月 1 日是星期一。 点击下个月的第一天(可以点击的几个灰色)时,月份不再切换。所有以前的工作。
我做了一些具体的隔离测试:
-
在 XE6 下创建具有相同行为的最小应用程序 -> 仍然失败(当然)
在 Delphi 2006 下创建相同的最小应用程序 -> 一切正常。
我的直觉是 TMonthCalendar 现在采用 .Date 属性来定义要显示的月份,而在 D2006 上它曾经采用 .EndDate 属性。 不知道这是 VCL 演变还是 microsoft MonthCalendar 底层组件行为更改(因为我在 XP 然后 SEVEN 上编译)。
感谢您的帮助
有用的文档:
http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.ComCtrls.TMonthCalendar http://msdn.microsoft.com/en-us/library/system.windows.forms.monthcalendar(v=vs.110).aspx
【问题讨论】:
应该是VCL,我想,在W7上编译XE2没问题。顺便说一句,实际上,您的代码阻止了从 14 年 9 月切换到 14 年 10 月,因为当我选择 9 月 14 日时,代码将日期更改为 9 月 8 日,然后我只能切换到 10 月 8 日。 所以您在 Windows 7 上使用 XE2 VCL 尝试了相同的最小应用程序,它是否有效?这肯定表明 XE2 和 XE6 之间的 VCL 发生了变化。 【参考方案1】:很遗憾,我无法为您提供解决方案,但至少我对当前的行为有解释。
您面临的问题是 TMonthCalender 控件本身以及即使在使用多选时也会将哪些日期字段视为已选中。 如果你仔细看一下,你会注意到,即使有一天使用多选,它周围总是有圆点。该日期控制着重点关注的月份。 因此,现在您需要弄清楚如何在启用多项选择的情况下更改该行为。我尝试设置 Date 和 EndDate 属性,以便 EndDate 值实际上更低,因为我认为这样做会强制 MonthCalendar 在确定哪个月份为重点时选择弱的最后一天,但它没有效果。但是没有效果。
至于查找开始和结束星期日期,请使用以下函数:
TempDate := MonthCalendar1.Date;
WeekStart := StartOfTheWeek(TempDate);
WeekEnd := EndOfTheWeek(TempDate);
这两个函数都将星期一视为一周的第一天。
我希望我能帮助你更多。
【讨论】:
以上是关于TMonthCalendar 行为已更改的主要内容,如果未能解决你的问题,请参考以下文章
对 TMonthCalendar 使用 ScaleBy 方法
手动刷新 TMonthCalendar 的 BoldDays?
当 ListView.builder 顶部附近的项目高度被缓存但已更改时,如何从 animateTo 获得正常行为?