有关画布应用的日历屏幕模板的参考信息
对于 Power Apps 中的画布应用,了解日历屏幕模板中的每个重要控件对屏幕的整体默认功能有何作用。 这篇深入研究文章介绍行为公式以及确定控件如何响应用户输入的其他属性的值。 有关此屏幕默认功能的高深讨论,请参阅日历屏幕概述。
本主题重点介绍一些重要的控件,并说明这些控件的各种属性(如 Items 和 OnSelect)所设置的表达式或公式:
- 日历下拉列表 (dropdownCalendarSelection)
- 日历图标 (iconCalendar)
- 上个月 V 形 (iconPrevMonth)
- 下个月 V 形 (iconNextMonth)
- 日历库 (MonthDayGallery)(+ 子控件)
- 事件库 (CalendarEventsGallery)
先决条件
熟悉在 Power Apps 中创建应用时如何添加和配置屏幕及其他控件。
日历下拉列表
属性:Items
值:Office365.CalendarGetTables().value
此值是一个连接器操作,用于检索应用用户的 Outlook 日历。 您可以查看此操作检索的值。
属性:OnChange
值:Select(dropdownCalendarSelection)
当用户在列表中选择一个选项时,控件的 OnSelect 属性中的函数将运行。
属性:OnSelect
值:If 函数(显示在下面的代码块中)和其他几个函数(显示在后面的代码块中)。公式的这一部分仅在用户打开应用后第一次在下拉列表中选择选项时运行:
If( IsBlank( _userDomain ), UpdateContext( {_showLoading: true} ); Set( _userDomain, Right( User().Email, Len( User().Email ) - Find( "@", User().Email ) ) ); Set( _dateSelected, Today() ); Set( _firstDayOfMonth, DateAdd( Today(), 1 - Day( Today() ), Days ) ); Set( _firstDayInView, DateAdd( _firstDayOfMonth, -(Weekday(_firstDayOfMonth) - 1), Days ) ); Set( _lastDayOfMonth, DateAdd( DateAdd( _firstDayOfMonth, 1, Months ), -1, Days ) ) );
前面的代码定义以下变量:
- _userDomain:应用用户的公司域,反映在用户的电子邮件地址中。
- _dateSelected:当前日期(默认)。 日历库突出显示此日期,事件库显示该日期的计划事件。
- _firstDayOfMonth:当前月份的第一天。 因为
(Today + (1 - Today)) = Today - Today + 1 = 1
,所以此 DateAdd 函数始终返回该月的第一天。 - _firstDayInView:日历库可以显示的第一天。 除非月份从星期日开始,否则此值与该月的第一天不同。 为了避免显示上个月的整个星期,_firstDayInView 的值为
_firstDayOfMonth - Weekday(_firstDayOfMonth) + 1
。 - _lastDayOfMonth:当前月的最后一天(与下个月的第一天相同)减去一天。
每当用户在日历下拉列表中选择一个选项时(不仅是用户第一次打开应用时),If 函数之后的函数都会运行:
Set( _calendarVisible, false ); UpdateContext( {_showLoading: true} ); Set( _myCalendar, dropdownCalendarSelection2.Selected ); Set( _minDate, DateAdd( _firstDayOfMonth, -(Weekday( _firstDayOfMonth ) - 2 + 1), Days ) ); Set(_maxDate, DateAdd( DateAdd( _firstDayOfMonth, -(Weekday( _firstDayOfMonth ) - 2 + 1), Days ), 40, Days ) ); ClearCollect( MyCalendarEvents, Office365Outlook.GetEventsCalendarViewV2( _myCalendar.Name, Text( _minDate, UTC ), Text( _maxDate, UTC ) ).value ); UpdateContext( {_showLoading: false} ); Set( _calendarVisible, true )
前面的代码定义这些变量和一个集合:
- _calendarVisible:设置为 false,以在加载新选择时不显示日历。
- _showLoading:设置为 true,以在加载新选择时显示加载指示器。
- _myCalendar:设置为日历下拉列表控件的当前值,以检索正确的日历中的事件。
- _minDate:设置为与 _firstDayInView 相同的值。 此变量确定有哪些事件已从 Outlook 中检索到并缓存在应用中。
- _maxDate:设置为日历中的最后一个可查看日。 公式为
_firstDayInView + 40
。 日历最多显示 41 天,因此 _maxDate 变量始终反映最后一个可查看日,并确定哪些事件已从 Outlook 中检索到并缓存在应用中。 - MyCalendarEvents:设置为所选日历中用户事件的集合,范围从 _minDate 到 _maxDate。
- _showLoading:设置为 false;加载所有其他内容后,_calendarVisible 设置为 true。
颜色属性
有关常规颜色属性的信息,请参阅 Power Apps 中的颜色和边框属性。
日历下拉列表控件的唯一颜色属性:
- ChevronBackground - 日历下拉列表的背景色。
- ChevronDisabledBackground - 禁用的日历下拉列表的背景色。
- ChevronFill - 日历下拉列表的填充色。
- ChevronDisabledFill - 禁用的日历下拉列表的填充色。
- ChevronHoverBackground - 用户将鼠标指针停留在日历下拉列表上时日历下拉列表的背景色。
- ChevronHoverFill - 用户将鼠标指针停留在日历下拉列表上时日历下拉列表的填充色。
日历图标
属性:OnSelect
值:可将日历库重置为当前日期的四个 Set 函数:Set( _dateSelected, Today() ); Set( _firstDayOfMonth, DateAdd( Today(), 1 - Day( Today() ), Days) ); Set( _firstDayInView, DateAdd(_firstDayOfMonth, -(Weekday( _firstDayOfMonth ) - 2 + 1), Days)); Set( _lastDayOfMonth, DateAdd( DateAdd( _firstDayOfMonth, 1, Months ), -1, Days ) )
前面的代码重置显示正确的日历视图所需的所有日期变量:
- _dateSelected 重置为当前日期。
- _firstDayOfMonth 重置为当前月份的第一天。
- 选择当前月份后,_firstDayInView 将重置为第一个可查看日期。
- _lastDayOfMonth 重置为当前月份的最后一天。
本主题的日历下拉列表一节将更详细地说明这些变量。
上个月 V 形
属性:OnSelect
值:在日历库中显示上个月的四个 Set 函数和一个 If 函数:Set( _firstDayOfMonth, DateAdd( _firstDayOfMonth, -1, Months ) ); Set( _firstDayInView, DateAdd( _firstDayOfMonth, -(Weekday( _firstDayOfMonth ) - 2 + 1), Days ) ); Set( _lastDayOfMonth, DateAdd(DateAdd( _firstDayOfMonth, 1, Months ), -1, Days ) ); If( _minDate > _firstDayOfMonth, Collect( MyCalendarEvents, Office365Outlook.GetEventsCalendarViewV2( _myCalendar.Name, Text( _firstDayInView, UTC ), Text( DateAdd( _minDate, -1, Days ), UTC ) ).value ); Set( _minDate, _firstDayInView ) )
备注
_firstDayOfMonth、_firstDayInView 和 _lastDayOfMonth 的定义与本主题日历下拉列表一节中的定义基本相同。
每当用户选择上个月 V 形时,前面代码的前三行就会运行。 此代码设置显示正确的日历视图所需的变量。 其余代码仅在用户之前没有未为所选日历选择本月时运行。
如果是这种情况,_minDate 是在上个月显示时显示的第一天。 在用户选择此图标之前,_minDate 的最小可能值是当前月份的 23 日。 (当 3 月 1 日为星期六时,3 月的 _firstDayInView 是 2 月 23 日。)这意味着,如果用户尚未选择本月,_minDate 将大于新 _firstDayOfMonth,If 函数将返回 true。 代码运行,集合和变量更新:
MyCalendarEvents 使用 Office365Outlook.GetEventsCalendarViewV2 操作从所选日历中检索事件。 日期范围从 _firstDayInView 日期到 _minDate - 1。 由于 MyCalendarEvents 已经包含 _minDate 日期的事件,因此将从该日期减去 1,来获得新日期范围内的最大值。
_minDate 设置为当前的 _firstDayInView,因为这是检索到事件的第一个日期。 如果用户通过选择上个月 V 形返回到此日期,If 函数将返回 false;代码不会运行,因为此视图的事件已缓存在 MyCalendarEvents 中。
下个月 V 形
属性:OnSelect
值:在日历库中显示下个月的四个 Set 函数和一个 If 函数:Set( _firstDayOfMonth, DateAdd( _firstDayOfMonth, 1, Months ) ); Set( _firstDayInView, DateAdd( _firstDayOfMonth, -(Weekday( _firstDayOfMonth ) - 2 + 1), Days ) ); Set( _lastDayOfMonth, DateAdd( DateAdd( _firstDayOfMonth, 1, Months ), -1, Days ) ); If(_maxDate < _lastDayOfMonth, Collect(MyCalendarEvents, Office365Outlook.GetEventsCalendarViewV2(_myCalendar.Name, Text(DateAdd(_maxDate, 1, Days), UTC), Text(DateAdd(_firstDayInView, 40, Days)) ).value ); Set(_maxDate, DateAdd(_firstDayInView, 40, Days)) )
备注
_firstDayOfMonth、_firstDayInView 和 _lastDayOfMonth 的定义与本主题日历下拉列表一节中的定义基本相同。
前面代码的前三行(当用户选择下个月 V 形时运行)设置显示正确日历视图所需的变量。 其余代码仅在用户之前没有未为所选日历选择本月时运行。
在这种情况下,_maxDate 是在上个月显示时显示的最后一天。 在用户选择下个月 V 形前,_maxDate 的最大可能值为下个月的 13 日。 (当 2 月 1 日是平年的星期日时,_maxDate 是 3 月 13 日,即 _firstDayInView + 40 天。)这意味着,如果用户尚未选择本月,_maxDate 将大于新 _lastDayOfMonth,If 函数将返回 true。 代码运行,集合和变量更新:
MyCalendarEvents 使用 Office365Outlook.GetEventsCalendarViewV2 操作从所选日历中检索事件。 日期范围从 _maxDate + 1 天到 _firstDayInView + 40 天。 由于 MyCalendarEvents 已经包含 _minDate 日期的事件,因此将在该日期上加 1,来获得新日期范围内的最小值。 _firstDayInView + 40 是 _maxDate 的公式,因此范围中的第二个日期就是新 _maxDate。
_maxDate 设置为 _firstDayInView + 40 天,因为这是检索到事件的最后一天。 如果用户通过选择下个月 V 形返回到此日期,If 函数将返回 false;代码不会运行,因为此视图的事件已缓存在 MyCalendarEvents 中。
日历库
属性:Items
值:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41]
从 0 到 41 的集用于日历库中的项,因为在最坏的情况下,日历视图必须显示 42 个整天。 当月份的第一天发生在星期六,月份的最后一天发生在星期日时,将发生这种情况。 在这种情况下,日历在包含月份第一天的行中显示上个月的六天,在包含月份最后一天的行中显示下个月的六天。 这是 42 个唯一值,其中 30 个是所选月份的值。
属性:WrapCount
值:7
此值反映七天一周。
日历库中的标题控件
属性:Text
值:Day( DateAdd( _firstDayInView, ThisItem.Value, Days ) )
回想一下 _firstDayInView 定义为 (_firstDayOfMonth - 它的星期日期值) + 1。 这表明 _firstDayInView 始终是星期日,_firstDayOfMonth 始终位于 MonthDayGallery 的第一行。 由于这两点,_firstDayInView 始终位于 MonthDayGallery 的第一个单元内。 ThisItem.Value 是 MonthDayGallery 项属性中该单元的编号。 因此,以 _firstDayInView 为起点,每个单元显示 _firstDayInView 的增量 + 各自的单元值。
属性:Fill
值:一个 If 函数:If( DateAdd( _firstDayInView, ThisItem.Value ) = Today() && DateAdd( _firstDayInView, ThisItem.Value ) = _dateSelected, RGBA( 0, 0, 0, 0 ), DateAdd( _firstDayInView, ThisItem.Value) = Today(), ColorFade( Subcircle.Fill, 0.67 ), Abs( Title.Text - ThisItem.Value) > 10, RGBA( 200, 200, 200, 0.3 ), RGBA( 0, 0, 0, 0 ) )
如对 Text 属性的说明中所述,
DateAdd(_firstDayInView, ThisItem.Value)
表示可见单元中的日期。 考虑到这一点,前面的代码执行以下比较:如果单元的值是当前日期,并且此单元等于 _dateSelected,请不要提供填充值。
如果单元的值是当前日期,但不等于 _dateSelected,请提供 ColorFade 填充。
最后一个比较不清晰。 它是单元中的实际文本值与单元项的值(显示的数字和项编号)之间的比较。
为了更好地理解这一点,请思考一下 2018 年 9 月,该月从星期六开始到星期日结束。 在这种情况下,日历在第一行中显示 8 月 26 日至 31 日和 9 月 1 日,并显示
Abs(Title.Text - ThisItem.Value) = 26
直到 9 月 1 日。 然后是Abs(Title.Text - ThisItem.Value) = 5
。 它将保持为 5,直到日历的最后一行,其显示 9 月 30 日和 10 月 1 日至 6 日。 在这个Abs(Title.Text - ThisItem.Value)
中,9 月 30 日仍为 5,而 10 月的日期将为 35。模式如下:对于在上个月显示的日期,
Abs(Title.Text - ThisItem.Value)
将始终等于显示的第一天的Title.Text
值。 对于在下个月显示的日期,Abs(Title.Text - ThisItem.Value)
将始终等于该月第一个单元(在本例中为 10 月 1 日)的 MonthDayGallery 项值减去 1。 而且,最重要的是,对于当前所选月份中显示的日期,Abs(Title.Text - ThisItem.Value)
也会始终等于该月第一项的值减去 1,并且永远不会超过 5,如前一个示例所示。 因此,将公式编写为Abs(Title.Text - ThisItem.Value) > 5
是完全正确的。此语句检查日期值是否在当前所选月份之外。 如果是这样,填充部分不透明的灰色。
备注
您可以通过在库中插入标签控件并将其 Text 属性设置为此值,来自行检查最后一个比较的有效性:
Abs(Title.Text - ThisItem.Value)
。属性:Visible
值:!( DateAdd( _firstDayInView, ThisItem.Value, Days ) - Weekday( DateAdd( _firstDayInView, ThisItem.Value,Days ) ) + 1 > _lastDayOfMonth )
前面的语句检查单元是否位于没有当前所选月份的日期的行中。 回想一下,从任何一天的日期值中减去这一天的星期日期值并加 1 始终会返回该日期所在行中的第一项。 因此,此语句检查行中的第一天是否在可查看月份的最后一天之后。 如果是这样,它将不会显示,因为整个行包含的是下个月的日期。
属性:OnSelect
值:将 _dateSelected 变量设置为所选单元的日期的一个 Set 函数:Set( _dateSelected, DateAdd( _firstDayInView, ThisItem.Value, Days ) )
日历库中的圆圈控件
属性:Visible
值:确定是否在选定日期计划了任何活动以及子圆圈和标题控件是否可见的公式:CountRows( Filter( MyCalendarEvents, DateValue( Text( Start ) ) = DateAdd( _firstDayInView, ThisItem.Value, Days ) ) ) > 0 && !Subcircle.Visible && Title.Visible
如果有任何活动的开始字段等于该单元的日期,标题控件可见,且子圆圈控件不可见,那么圆圈控件可见。 换言之,当这一天至少发生一个事件且未选择这一天时,此控件才可见。 如果选中,这一天的事件将显示在 CalendarEventsGallery 控件中。
日历库中的订阅控件
属性:Visible
值:DateAdd( _firstDayInView, ThisItem.Value ) = _dateSelected && Title.Visible
当 _dateSelected 等于单元的日期,并且标题控件可见时,订阅控件可见。 换言之,当单元是当前选定日期时,将出现此控件。
事件库
属性:Items
值:用于对事件库进行排序和筛选的公式:SortByColumns( Filter( MyCalendarEvents, Text( Start, DateTimeFormat.ShortDate ) = Text( _dateSelected, DateTimeFormat.ShortDate ) ), "Start" )
MyCalendarEvents 集合包含 _minDate 到 _maxDate 之间的所有事件。 为了仅显示所选日期的事件,在 MyCalendarEvents 上应用了筛选器,来显示开始日期等于 \ _dateSelected 的事件。 然后,按开始日期对项进行排序,以按顺序排列它们。
后续步骤
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈