模块拆解-安排表(vb.net,Arrangement,高考倒计时)

发布于:2025-09-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

前言

我其实很想新建一个分区专门拆解模块来讲解大型项目的,正好,高考倒计时是我第一个成功能够正常运行的第二个大型项目,此模块非Module!

这一次我们拆解——安排表

作为桌面壁纸程序,这个模块会有对应的绘制教程,然而各个模块已经被拆解,因此我会尽量讲的详细,并且把所有重要的知识点放在目录,希望大家可以利用好目录这个东西,看一下目录基本上要解决什么问题只需要点到哪里就行。

目录

前言

窗口设计

所有模块

        1、序列化和反序列化保存和加载配置文件,可以参考VB.net序列化和反序列化的使用方法和实用场景

        2、上下移动安排表和子项

        3、绘制多行文字

                i、获取文字绘制矩形(范围)

                ii、绘制所有文字(重点,范围)

        4、经典Windows气球通知

模块解析

2、我们举例ListView这个控件的向上移动的例子

3、绘制文字

i)、获取文字的矩形

ii)、绘制特定的安排项

输出文字部分

4、Windows气球通知

什么时候执行?

结语

窗口设计

本次窗口设计简易,紧凑但美观,虽然我们的专业方向是美术与设计类,但是这是后期的问题,我们目前只要搞定后端原理即可,后期可以再优化前端

所有模块

        1、序列化和反序列化保存和加载配置文件,可以参考VB.net序列化和反序列化的使用方法和实用场景

        2、上下移动安排表和子项

        3、绘制多行文字

                i、获取文字绘制矩形(范围)

                ii、绘制所有文字(重点,范围)

        4、经典Windows气球通知

模块解析

2、我们举例ListView这个控件的向上移动的例子

我们的预期是选择一项,可以持续向上移动直到顶部,不能再移动

ar为MyArrangement的一个实例

Private Sub Button18_Click(sender As Object, e As EventArgs) Handles ButUpSub.Click
    Dim si = ViewSelectIndex
    If ViewSelectIndex > 0 Then
        ar.AllList(SelectIndex).SubList.Move(ViewSelectIndex, ViewSelectIndex - 1)
        ViewListReload()
        ViewSelectIndex = si - 1
    End If
End Sub

ar的类结构为(如下图),显然,SubList为一个可移动集合,因此,如果你的基本集合如果只是List的话请直接换成ObservableCollection,他们不会冲突,只是多一个Move方法,仅此而已!

秘密就在于ObservableCollection!

3、绘制文字

我们的预期是:表头在第一行,下边依次是各个子安排,包含可选的(星期,精确分钟,是否通知)

i)、获取文字的矩形

这里需要实例化一个Graphics对象,你可以把bitmap设置为(1,1)大小,节约内存开销,这里不需要bitmap参与,所以我们直接调用MeasureString方法即可

Public Function GetStringSize(s As String, font As Font, sf As StringFormat) As Size
    Dim g = Graphics.FromImage(New Bitmap(100, 100))
    Dim ScreenSize As New Size(CInt(g.MeasureString(s, font, 9999, sf).Width), CInt(g.MeasureString(s, font, 9999, sf).Height))
    Return ScreenSize
End Function

ii)、绘制特定的安排项

预期目标:对单个安排表,绘制子安排,通过循环遍历子安排,获取子安排的输出文字,由于我们现在只支持横向排列单个字符串,所以,如果你需要竖版排列字符串,可以试试

New StringFormat(2)

,然后把部分比如说MaxHeight改成MaxWidth等等。

横板字符串排列代码,通过获取字符串矩形大小获取所有要绘制的字符串的最大宽度,通过所有字符串的高度,获取总高度,完美!

Function DrawArrangement(ar As MyArrangment, index As Integer) As Bitmap
    Dim MaxWidth As Integer
    Dim MaxHeight As Integer
    Dim OriHeight
    MaxWidth = GetStringSize(ar.AllList(index).Title, ar.AllList(index).Font, New StringFormat(1)).Width
    MaxHeight = GetStringSize(ar.AllList(index).Title, ar.AllList(index).Font, New StringFormat(1)).Height
    OriHeight = MaxHeight
    For i = 0 To ar.AllList(index).SubList.Count - 1
        If MaxWidth < GetStringSize(ar.AllList(index).SubList(i).GetString, ar.AllList(index).Font, New StringFormat(1)).Width Then
            MaxWidth = GetStringSize(ar.AllList(index).SubList(i).GetString, ar.AllList(index).Font, New StringFormat(1)).Width
        End If
    Next
    MaxHeight *= ar.AllList(index).SubList.Count + 1

    Dim bmp As New Bitmap(MaxWidth, MaxHeight)
    Dim g = Graphics.FromImage(bmp)
    g.DrawString(ar.AllList(index).Title, ar.AllList(index).Font, New SolidBrush(ar.AllList(index).Color), New Point(0, 0))

    For i = 0 To ar.AllList(index).SubList.Count - 1
        g.DrawString(ar.AllList(index).SubList(i).GetString, ar.AllList(index).Font, New SolidBrush(ar.AllList(index).Color), New Point(0, OriHeight * (i + 1)))
    Next
    Return bmp
End Function
输出文字部分
Function GetString() As String
    Dim d As String = ""
    For Each h In Days
        d &= (h & ",")
    Next
    If d = "-1," Or d.Trim = "" Then
        d = ""
    Else
        d = "星期" & d
    End If
    Dim c As String
    If Format(StartTime, "yyyy-MM-dd HH:mm") <> Format(EndTime, "yyyy-MM-dd HH:mm") Then
        c = "(" & Format(StartTime, Arrangement.GetFormat(IsMinite)) & " ~ " & Format(EndTime, Arrangement.GetFormat(IsMinite)) & ")"
    End If
    Return Name & c & d
End Function

4、Windows气球通知

预期目标:定点执行子安排的启动和结束,可以自己增加执行脚本(本教程不展示)

编写Trigger类,执行LoadTrigger方法时,计算需要等待的时间,开始计时,直到被执行时间到达,执行Post方法,如果单个trigger不需要了,那么就调用UnLoad方法,彻底销毁等待线程

Public Class Trigger
    Dim PostInfo As String
    Dim t As New Threading.Timer(AddressOf Post)
    Sub New()

    End Sub
    Sub New(d As DateTime, info As String)
        SetDate(d, info)
    End Sub
    Function SetDate(d As DateTime, info As String)
        PostInfo = info

        Dim now = Date.Now
        Dim delta = Math.Ceiling((d - now).TotalSeconds)
        If delta < 0 Then
            Exit Function
        Else
            t.Change(CInt(delta) * 1000, 0)
        End If

    End Function

    Sub Post()
        Dim n = MainForm.NotifyIcon1
        n.BalloonTipTitle = "高考倒计时通知"
        n.BalloonTipText = PostInfo
        n.ShowBalloonTip(0)
    End Sub
    Sub UnLoad()
        t.DisposeAsync()
    End Sub

End Class

什么时候执行?

在每一次重新加载子安排表,重新加载安排,包括但不限于子安排的删除、移动、修改,本地计算机时间更变等,一系列会变的因素要考虑周全!

TodayTrigger是符合当日的子安排项目,以节约内存开销

Sub LoadTrigger()
    For Each i In TodayTriggers
        i.UnLoad()
    Next
    TodayTriggers.Clear()
    Dim now = Date.Now
    Dim week
    If now.DayOfWeek = 0 Then
        week = 7
    Else
        week = now.DayOfWeek
    End If

    For Each a In ar.AllList
        For Each s In a.SubList
            If s.IsInform Then
                If s.IsMinite Then '''精确到分钟,受星期控制
                    If s.Days.Contains(week) Or s.Days(0) = -1 Then
                        Dim start = New Date(now.Year, now.Month, now.Day, s.StartTime.Hour, s.StartTime.Minute, 0)
                        Dim [end] = New Date(now.Year, now.Month, now.Day, s.EndTime.Hour, s.EndTime.Minute, 0)
                        TodayTriggers.Add(New Trigger(start, "来自安排表:" & a.Title & vbCrLf & "  子安排项:" & s.Name & vbCrLf & "事件活动:启动"))
                        TodayTriggers.Add(New Trigger([end], "来自安排表:" & a.Title & vbCrLf & "  子安排项:" & s.Name & vbCrLf & "事件活动:结束"))
                    End If
                Else '''不精确到分钟,受日期控制
                    If s.StartTime.Day = now.Day And s.StartTime.Month = now.Month And s.StartTime.Year = now.Year Then
                        TodayTriggers.Add(New Trigger(s.StartTime, "来自安排表:" & a.Title & vbCrLf & "  子安排项:" & s.Name & vbCrLf & "事件活动:启动"))
                    End If
                    If s.EndTime.Day = now.Day And s.EndTime.Month = now.Month And s.EndTime.Year = now.Year Then
                        TodayTriggers.Add(New Trigger(s.EndTime, "来自安排表:" & a.Title & vbCrLf & "  子安排项:" & s.Name & vbCrLf & "事件活动:结束"))
                    End If
                End If
            End If
        Next
    Next
End Sub

结语

今后会更多的拆解代码,至于完整源代码,请点开我的主页,下载免费资源研究!!


网站公告

今日签到

点亮在社区的每一天
去签到