@@ -14,7 +14,7 @@ public class TCalendar : TDesignComponentBase
1414 /// <summary>
1515 /// 日历的模式。
1616 /// </summary>
17- [ Parameter ] public CalendarMode Mode { get ; set ; } = CalendarMode . Year ;
17+ [ Parameter ] public CalendarMode Mode { get ; set ; } = CalendarMode . Mounth ;
1818
1919 /// <summary>
2020 /// 是否显示周末。<see cref="CalendarMode.Mounth"/> 有效。
@@ -128,7 +128,7 @@ void BuildCalendarHeader(RenderTreeBuilder builder)
128128 foreach ( var item in DayOfWeekList )
129129 {
130130 //不显示周末
131- if ( ! ShowWeekend && new [ ] { DayOfWeek . Saturday , DayOfWeek . Sunday } . Contains ( item ) )
131+ if ( IsSkipWeekend ( item ) )
132132 {
133133 continue ;
134134 }
@@ -145,6 +145,13 @@ void BuildCalendarHeader(RenderTreeBuilder builder)
145145 . Close ( ) ;
146146 }
147147
148+ /// <summary>
149+ /// 是否跳过周末
150+ /// </summary>
151+ /// <param name="day"></param>
152+ /// <returns></returns>
153+ bool IsSkipWeekend ( DayOfWeek day ) => ! ShowWeekend && new [ ] { DayOfWeek . Saturday , DayOfWeek . Sunday } . Contains ( day ) ;
154+
148155 /// <summary>
149156 /// 构建日历的主体。
150157 /// </summary>
@@ -156,7 +163,7 @@ void BuildCalendarBody(RenderTreeBuilder builder)
156163 {
157164 if ( Mode == CalendarMode . Mounth )
158165 {
159-
166+ BuildMonthBody ( body ) ;
160167 }
161168 else
162169 {
@@ -179,10 +186,7 @@ void BuildYearBody(RenderTreeBuilder builder)
179186 var sequence = 0 ;
180187 for ( int i = 1 ; i <= 12 ; i ++ )
181188 {
182- builder . AddContent ( sequence + 2 , cell =>
183- {
184- BuildBodyCell ( cell , $ "{ i } 月", now : CurrentYear == Year && CurrentMonth == i ) ;
185- } ) ;
189+ BuildBodyCell ( builder , $ "{ i } 月", now : CurrentYear == Year && CurrentMonth == i ) ;
186190 if ( i % 4 == 0 )
187191 {
188192 sequence += 4 * i ;
@@ -192,6 +196,88 @@ void BuildYearBody(RenderTreeBuilder builder)
192196 builder . CloseElement ( ) ;
193197 }
194198
199+ /// <summary>
200+ /// 构建月视图。
201+ /// </summary>
202+ /// <remarks>
203+ /// 要计算日期。
204+ /// </remarks>
205+ /// <param name="builder"></param>
206+ void BuildMonthBody ( RenderTreeBuilder builder )
207+ {
208+ builder . OpenElement ( 0 , "tr" ) ;
209+ builder . AddAttribute ( 1 , "class" , "t-calendar__table-body-row" ) ;
210+
211+ #region 构建上个月剩余的几天在当前这个月的日历
212+ //当前年月的第一天
213+ var firstDay = new DateTime ( CurrentYear , CurrentMonth , 1 ) ;
214+
215+ var firstDayOfWeek = firstDay . DayOfWeek ; //第一天所在周几
216+ var firstDayOfWeekIndex = ( int ) firstDayOfWeek ;
217+
218+ var findLastMonthDayIndex = DayOfWeekList . FindIndex ( m => m == firstDayOfWeek ) ;
219+
220+ var lastDays = firstDay . AddDays ( - findLastMonthDayIndex ) ;
221+ for ( int i = 0 ; i < findLastMonthDayIndex ; i ++ )
222+ {
223+ var day = i + lastDays . Day ;
224+
225+ var lastMonthDateTime = new DateTime ( lastDays . Year , lastDays . Month , day ) ;
226+
227+ if ( IsSkipWeekend ( lastMonthDateTime . DayOfWeek ) )
228+ {
229+ continue ;
230+ }
231+
232+ BuildBodyCell ( builder , day . ToString ( ) , true ) ;
233+ }
234+ #endregion
235+
236+ #region 构建这个月的日历
237+ var daysOfThisMonth = DateTime . DaysInMonth ( CurrentYear , CurrentMonth ) ; //这个月有多少天
238+ for ( int i = 0 ; i < daysOfThisMonth ; i ++ )
239+ {
240+ var day = i + 1 ;
241+ var currentDateTime = new DateTime ( CurrentYear , CurrentMonth , day ) ;
242+ if ( IsSkipWeekend ( currentDateTime . DayOfWeek ) )
243+ {
244+ ClosePrevRowAndBuildNewRow ( builder , i + 10 ) ; //跳过周末要换行
245+ continue ;
246+ }
247+
248+ var today = DateTime . Today ;
249+ BuildBodyCell ( builder , day . ToString ( ) , false , today == currentDateTime ) ;
250+
251+ if ( ( i + firstDayOfWeekIndex ) % 7 == 0 )
252+ {
253+ ClosePrevRowAndBuildNewRow ( builder , i + 10 ) ;
254+ }
255+ }
256+ #endregion
257+
258+ #region 构建下个月的头几天到当前日历
259+ var lastDateTime = new DateTime ( CurrentYear , CurrentMonth , daysOfThisMonth ) ; //本月最后一天
260+ var lastDayOfWeek = lastDateTime . DayOfWeek ; //最后一天是周几
261+
262+ var lastDayOfWeekIndex = DayOfWeekList . FindIndex ( m => m == lastDayOfWeek ) ;
263+
264+ var nextMonth = lastDateTime . AddDays ( 1 ) ;
265+ for ( int i = 0 ; i <= ( 5 - lastDayOfWeekIndex ) ; i ++ )
266+ {
267+ var day = i + 1 ;
268+ var nextMonthDateTime = new DateTime ( nextMonth . Year , nextMonth . Month , day ) ;
269+ if ( IsSkipWeekend ( nextMonthDateTime . DayOfWeek ) )
270+ {
271+ continue ;
272+ }
273+
274+ BuildBodyCell ( builder , day . ToString ( ) , true ) ;
275+ }
276+ #endregion
277+
278+ builder . CloseElement ( ) ;
279+ }
280+
195281 /// <summary>
196282 /// 关闭上一个 tr 并开始新的 tr。用于动态换行。
197283 /// </summary>
@@ -213,22 +299,25 @@ private static void ClosePrevRowAndBuildNewRow(RenderTreeBuilder builder, int se
213299 /// <param name="now"></param>
214300 static void BuildBodyCell ( RenderTreeBuilder builder , string content , bool disabled = false , bool now = default )
215301 {
216- builder . Div ( "t-calendar__table-body-cell" )
217- . Class ( "t-is-disabled" , disabled )
218- . Class ( "t-calendar__table-body-cell--now" , now )
219- . Class ( "t-is-checked" , now )
220- . Content ( cell =>
221- {
222- cell . Div ( )
223- . Style ( "display: flex; flex-direction: column; align-items: flex-end;" )
224- . Content ( inner =>
225- {
226- inner . Div ( "t-calendar__table-body-cell-display" ) . Content ( content ) . Close ( ) ;
227- inner . Div ( "t-calendar__table-body-cell-content" ) . Close ( ) ;
228- } )
229- . Close ( ) ;
230- } )
231- . Close ( ) ;
302+ builder . AddContent ( 0 , tr =>
303+ {
304+ tr . Div ( "t-calendar__table-body-cell" )
305+ . Class ( "t-is-disabled" , disabled )
306+ . Class ( "t-calendar__table-body-cell--now" , now )
307+ . Class ( "t-is-checked" , now )
308+ . Content ( cell =>
309+ {
310+ cell . Div ( )
311+ . Style ( "display: flex; flex-direction: column; align-items: flex-end;" )
312+ . Content ( inner =>
313+ {
314+ inner . Div ( "t-calendar__table-body-cell-display" ) . Content ( content ) . Close ( ) ;
315+ inner . Div ( "t-calendar__table-body-cell-content" ) . Close ( ) ;
316+ } )
317+ . Close ( ) ;
318+ } )
319+ . Close ( ) ;
320+ } ) ;
232321 }
233322}
234323
0 commit comments