關於 Power Apps 中的畫布應用程式,瞭解行事曆畫面範本中的每個重要控制項如何提供畫面控制項的整體預設功能。 這種深入研究顯示行為公式及其他屬性值,判定控制項如何回應使用者的輸入。 如需此畫面控制項預設功能的高等級討論,請參閱 行事曆畫面總覽。
此主題會重點標示一些重大控制項,並解釋設定這些控制項的各種屬性 (例如 Items 與 OnSelect) 的運算式或公式:
- 行事曆下拉式清單 (dropdownCalendarSelection)
- 行事曆圖示 (iconCalendar)
- Previous-month chevron (iconPrevMonth)
- Next-month chevron (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:設定為 calendar drop-down 控制項的當前值,讓來自正確行事曆的事件可以進行檢索。
- _minDate:設定為與 _firstDayInView 相同的值。 這個變數會判定已從 Outlook 檢索並在應用程式中快取的事件。
- _maxDate:設定為行事曆中的最後一個可檢視日。 公式為
_firstDayInView + 40
。 行事曆最多顯示 41 天的時間,因此 _maxDate 變數會一直反映上次可查看日期,並判定已從 Outlook 檢索或已在應用程式中快取的事件。 - MyCalendarEvents:從選取的行事曆設定為使用者事件的集合物件,範圍從 _minDate 到 _maxDate。
- _showLoading:設定為 false;_calendarVisible 則在已經載入所有其他之後設定為 true。
色彩屬性
如欲了解一般色彩屬性,請參閱 Power Apps 中的色彩和邊框屬性。
行事曆下拉式選單控制項的獨特色彩屬性:
- ChevronBackground - 行事曆下拉式選單的背景色。
- ChevronBackgroundBackground - 停用的行事曆下拉式選單的背景色。
- 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 重設為今天所屬月份的最後一天。
本主題的 Calendar drop-down 章節會更詳細說明這些變數。
上個月 chevron
屬性: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 的定義幾乎與本主題的 Calendar drop-down 章節相同。
每當使用者選取上個月 chevron 時,就會執行先前程式碼的前三行。 此程式碼設定顯示適度行事曆視圖所需的變數。 其餘的程式碼只有在使用者先前尚未針對選取的行事曆選取本月時才執行。
這種情況下,_minDate 是顯示上個月時出現的第一天。 在使用者選取圖示之前,_minDate 的最小可能值是本月 23 日。 (當 3 月 1 日逢星期六時,三月的 _firstDayInView 是 2 月 23 日)。那表示如果使用者尚未選取本月,_minDate 會大於新的 _firstDayOfMonth,而且If 函數返回 true。 程式碼執行,集合物件和變數更新:
MyCalendarEvents 使用 Office365Outlook.GetEventsCalendarViewV2 作業從所選行事曆中擷取事件。 日期範圍在 _firstDayInView 日期與 _minDate -1 之間。 因為 MyCalendarEvents 已經包含 _minDate 日期當天的事件,所以這個新日期範圍的最大值是該日期減 1。
_minDate 設定為目前的 _firstDayInView, 因為這是已經檢索事件的第一天。 如果使用者藉由選取上個月 chevron 返回此日期,則 If 函數返回 false;因為此視圖事件已在 MyCalendarEvents 中快取,所以無法執行程式碼。
下個月 chevron
屬性: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 的定義幾乎與本主題的 Calendar drop-down 章節相同。
上述程式碼的前三行在使用者選取下個月 chevron 執行時,請設定顯示適當行事曆視圖所需的變數。 其餘的程式碼只有在使用者先前尚未針對選取的行事曆選取本月時才執行。
那種情況下,_maxDate 是顯示上個月時出現的最後一天。 在使用者選取下個月 chevron 之前,_maxDate 的最大可能值是下個月的 13 日。 (當 2 月 1 日逢非閨年星期日時,_maxDate 是 3 月 13 日,即 _firstDayInView + 40 天)。那表示如果使用者尚未選取本月,_minDate 會大於新的 _firstDayOfMonth,而且 If 函數返回 true。 程式碼執行,集合物件和變數更新:
MyCalendarEvents 使用 Office365Outlook.GetEventsCalendarViewV2 作業從所選行事曆中擷取事件。 日期範圍在 _maxDay + 1 天與 _firstDayInView +40 天之間。 因為 MyCalendarEvents 已經包含 _minDate 日期當天的事件,因此 1 會新增到此新日期範圍的最小值日期。 _firstDayInView + 40 是 maxDate**_** 的公式,因此範圍中的第二個日期只是新的 _maxDate。
_maxDate 設定為 _firstDayInView + 40 天因為這是已經檢索事件的最後一天。 如果使用者藉由選取下個月 chevron 返回此日期,則 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 + 各自儲存格值的累加值。
屬性:填色
值:一個 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 年九月,這是在星期六開始並在星期日結束的月份。 在此案例中,行事曆顯示八月 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)
將永遠等於當月第一個儲存格的 MonthDayGallery 項目值 (本案例中,即 10 月 1 日) 減 1。 而且最重要的是在目前選取月份顯示的天數,Abs(Title.Text - ThisItem.Value)
也會一直等於當月第一個項目值減 1,絕不會超過 5,如前範例所示。 因此將公式寫成Abs(Title.Text - ThisItem.Value) > 5
是最有效的方式。本句檢查日期值是否在目前選取月份範圍外。 如果是,Fill 會部分呈不透明灰色。
注意
您可以藉由將標籤控制項插入資源庫,並將其 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 ) )
行事曆資源庫中的 Circle 控制項
屬性:Visible
值:判定是否已為選取日期排程任何事件及是否能看見 Subcircle 和標題控制項的公式:CountRows( Filter( MyCalendarEvents, DateValue( Text( Start ) ) = DateAdd( _firstDayInView, ThisItem.Value, Days ) ) ) > 0 && !Subcircle.Visible && Title.Visible
如果任何事件的 Start 欄位等於該儲存格的日期,如果看得見標題控制項,而看不見 Subcircle 控制項,就能看見 Circle 控制項。 換言之,這天至少發生一個事件,且這天並未被選取時看得見此控制項。 如果已選取,該日事件會在 CalendarEventsGallery 控制項中顯示。
行事曆資源庫中的 Subcircle 控制項
屬性:Visible
值:DateAdd( _firstDayInView, ThisItem.Value ) = _dateSelected && Title.Visible
當 _dateSelected 等於儲存格日期,且看得見標題控制項時,就會看見 Subcircle 控制項。 換言之,當儲存格是目前選取的日期時,就會顯示此控制項。
事件資源庫
屬性:Items
值:排序和篩選事件資源庫的公式:SortByColumns( Filter( MyCalendarEvents, Text( Start, DateTimeFormat.ShortDate ) = Text( _dateSelected, DateTimeFormat.ShortDate ) ), "Start" )
MyCalendarEvents 集合物件包含 _minDate 與 _maxDate 之間的所有事件。 為了只顯示選取日期的事件,請在 MyCalendarEvents 上套用篩選條件,顯示開始日期等於 \ _dateSelected 的事件。 然後根據開始日期排序各項目,並將它們按順序排列。