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 获得正常行为?

Django LOGIN_REDIRECT_URL 更改不会影响行为

在表格视图中更改单元格的背景行为不符合预期[关闭]

更改 Ctrl + Tab 行为以在 Visual Studio 中的文档之间移动