You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Basic Express 2010日历控件如何设置多组可选日期范围?

实现WinForms MonthCalendar多组可选日期范围的解决方案

你之前遇到的问题其实很典型——MonthCalendar的MinDate和MaxDate确实只能设置单个连续的可选范围,多次赋值肯定会覆盖掉之前的设置,根本没法实现多组独立的可选区间。至于你说的BlackoutDates没生效,大概率是用法没搞对,咱们一步步来理清楚怎么实现需求。

核心思路:用BlackoutDates做"排除法"

BlackoutDates的作用是标记不可选的日期,所以要实现多组可选范围,咱们反过来操作:先确定所有不允许选择的日期/区间,把它们加入黑名单,剩下的自然就是可选的多组范围了。

具体实现步骤

1. 定义你的多组允许日期范围

首先把你需要开放的可选区间整理成列表,比如你提到的两组:

' 定义允许的日期范围列表
Dim allowedRanges As New List(Of Tuple(Of DateTime, DateTime))()
allowedRanges.Add(Tuple.Create(New DateTime(2019, 4, 2), DateTime.Today))
allowedRanges.Add(Tuple.Create(New DateTime(2019, 4, 12), New DateTime(2019, 4, 24)))

2. 设置全局的Min/Max范围(可选但推荐)

先把MonthCalendar的整体可选边界设为所有允许区间的最小起始和最大结束,避免用户看到完全无关的日期:

' 计算全局最小和最大日期
Dim globalMin As DateTime = allowedRanges.Min(Function(r) r.Item1)
Dim globalMax As DateTime = allowedRanges.Max(Function(r) r.Item2)

MonthCalendar1.MinDate = globalMin
MonthCalendar1.MaxDate = globalMax

3. 批量添加不可选日期到BlackoutDates

这里分两种情况,根据你的日期范围大小选择:

情况1:日期范围小(比如几个月),直接遍历每一天

这种方法简单直观,适合小范围日期:

' 先清空之前的黑名单设置
MonthCalendar1.BlackoutDates.Clear()

Dim currentDate As DateTime = globalMin
While currentDate <= globalMax
    ' 检查当前日期是否在任意一个允许区间内
    Dim isAllowed As Boolean = allowedRanges.Any(Function(r) currentDate >= r.Item1 AndAlso currentDate <= r.Item2)
    
    ' 如果不在允许区间,就加入黑名单
    If Not isAllowed Then
        MonthCalendar1.BlackoutDates.Add(New CalendarDateRange(currentDate, currentDate))
    End If
    
    currentDate = currentDate.AddDays(1)
End While
情况2:日期范围大(比如几年),添加连续不可选区间

如果允许的范围跨度过大,遍历每一天效率会很低,这时候可以计算出允许区间之间的空白部分,把这些连续的空白区间直接加入黑名单:

MonthCalendar1.BlackoutDates.Clear()

' 先把允许的区间按起始日期排序
Dim sortedRanges = allowedRanges.OrderBy(Function(r) r.Item1).ToList()
Dim previousEnd As DateTime = globalMin.AddDays(-1)

For Each range In sortedRanges
    ' 检查当前区间和上一个区间之间是否有空白
    If range.Item1 > previousEnd.AddDays(1) Then
        ' 把空白区间加入黑名单
        MonthCalendar1.BlackoutDates.Add(New CalendarDateRange(previousEnd.AddDays(1), range.Item1.AddDays(-1)))
    End If
    ' 更新上一个区间的结束日期(取较大值,避免区间重叠的情况)
    previousEnd = Math.Max(previousEnd, range.Item2)
Next

' 处理最后一个允许区间之后的日期
If previousEnd < globalMax Then
    MonthCalendar1.BlackoutDates.Add(New CalendarDateRange(previousEnd.AddDays(1), globalMax))
End If

为什么你之前的BlackoutDates没生效?

大概率是你搞反了逻辑——可能你把允许的日期加到了BlackoutDates里,或者没有先清空之前的黑名单设置,导致新的设置被旧的覆盖了。按照上面的方法,把不允许的日期/区间加入BlackoutDates,就能正常生效了。

最后,选中的日期存入Access数据库的逻辑和之前一样,用SQL语句插入即可,这个部分不受日期选择限制的影响。

内容的提问来源于stack exchange,提问作者LAKing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:18:51