如何使用 MS SQL 数据库在 ASP.NET 和 C# 中实现日历布局逻辑

How to implement the calendar layout logic in ASP.NET and C# with MS SQL Database

我在学校有这个项目,我创建了一个包含主页、会员注册、会员登录、会员个人资料和管理员登录页面的项目我想在用户登录时在我的主页上实现这个布局,并且能够 select 员工在家工作的日期应该选择一个日期并将其插入数据库,以便雇主查看谁在该特定日期或日期在家工作。

好吧,如果我们把它分解一下呢?

我们需要左侧的列表框来显示员工的

所以,放入一个列表框,这样说:

        <div style="float:left">
            <asp:ListBox ID="lstEmployee" runat="server" 
                DataValueField="ID"
                DataTextField="EmpName" Height="270px" Width="125px" 
                AutoPostBack="True" 
                OnSelectedIndexChanged="lstEmployee_SelectedIndexChanged" >
            </asp:ListBox>
        </div>

我们要加载的代码是这样的:

    DateTime dtStart, dtEnd;    // start and end of this month
    DateTime CalStart, CalEnd;  // start and end of the whole cal display

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            LoadEmployee();
            LoadCal();
        }
    }

    void LoadEmployee()
    {
        // load up employee listbox
        SqlCommand cmdSQL = new SqlCommand(
          "SELECT ID,(FirstName + ' ' + LastName) as EmpName " +
          "FROM Employee ORDER BY FirstName");

        lstEmployee.DataSource = MyRstP(cmdSQL);
        lstEmployee.DataBind();
    }

现在我们有了这个:

好的,现在我们需要一个日历。嗯,好的,看看outlook,我们看到我们需要6行一个“东西”。

我认为是一个简单的 Listview,对于每一行(其中 6 行),我们需要一个数据 table,包含 1-7 天的数据。

所以,一个简单的列表视图,一行 - 但我们吐出其中的 6 个。

我们希望日历可以点击,所以每一天都是一个按钮 - LinkBut​​ton 应该可以正常工作。

因此,列表视图可能是这样的:

        <div style="float:left;margin-left:25px">
        <asp:ListView ID="ListView1" runat="server" OnItemDataBound="ListView1_ItemDataBound1"  >
            <ItemTemplate>
              <tr id="OneRow" runat="server"> 
                 <td>
                    <asp:Linkbutton ID="L1" runat="server" Text='<%# Eval("Sun", "{0:dd}") %>'
                    bDate = '<%# Eval("Sun") %>' OnClick="L1_Click"  />
                </td>
                <td>
                    <asp:Linkbutton ID="L2" runat="server" Text='<%# Eval("Mon", "{0:dd}") %>' 
                     bDate = '<%# Eval("Mon") %>' OnClick="L1_Click" />
                </td>
                <td>
                    <asp:Linkbutton ID="L3" runat="server" Text='<%# Eval("Tue", "{0:dd}") %>' 
                    bDate = '<%# Eval("Tue") %>' OnClick="L1_Click" />
                </td>
                <td>
                    <asp:Linkbutton ID="L4" runat="server" Text='<%# Eval("Wed", "{0:dd}") %>'
                    bDate = '<%# Eval("Wed") %>' OnClick="L1_Click" />
                </td>
                <td>
                    <asp:Linkbutton ID="L5" runat="server" Text='<%# Eval("Thu", "{0:dd}") %>'
                    bDate = '<%# Eval("Thu") %>' OnClick="L1_Click" />
                </td>
                <td>
                    <asp:Linkbutton ID="L6" runat="server" Text='<%# Eval("Fri", "{0:dd}") %>'
                    bDate = '<%# Eval("Fri") %>' OnClick="L1_Click" />
                </td>
                <td>
                    <asp:Linkbutton ID="L7" runat="server" Text='<%# Eval("Sat", "{0:dd}") %>'
                    bDate = '<%# Eval("Sat") %>' OnClick="L1_Click" />
                </td>
              </tr>
            </ItemTemplate>
            <LayoutTemplate>
                <table id="itemPlaceholderContainer" runat="server" border="0" style="">
                <tr runat="server" style="">
                    <th runat="server" style="text-align:center" >Sun</th>
                    <th runat="server" style="text-align:center">Mon</th>
                    <th runat="server" style="text-align:center">Tue</th>
                    <th runat="server" style="text-align:center">Wed</th>
                    <th runat="server" style="text-align:center">Thr</th>
                    <th runat="server" style="text-align:center">Fri</th>
                    <th runat="server" style="text-align:center">Sat</th>
                </tr>
                <tr id="itemPlaceholder" runat="server"></tr>
                </table>
            </LayoutTemplate>
        </asp:ListView>

标记不多。

现在,我们需要加载数据,所以我们有:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            LoadEmployee();
            LoadCal();
        }
    }

加载日历的代码?一个6行7列的数据table,比如这样的代码:

    void LoadCal()
    {
        SetupDates();

        DataTable OneMonth = new DataTable();
        // add heading colums to table (Sun->Sat)
        for (int i = 0; i <= 6; i++)
        {
            DateTime d = CalStart.AddDays(i);
            string strCol = d.ToString("ddd"); // gets day of week as text (sun->sat)
            OneMonth.Columns.Add(new DataColumn(strCol, typeof(DateTime)));
        }

        DateTime dtPtr = CalStart;   // start a simple date counter - upper left
        // add 6 rows for calendar
        for (int i = 1; i <= 6; i++)
        {
            DataRow OneRow = OneMonth.Rows.Add();
            for (int wDay = 0; wDay <= 6; wDay++) // put date in each colum 1 - 7
            {
                OneRow[wDay] = dtPtr;   // shove date into cal square
                dtPtr = DateAndTime.DateAdd(DateInterval.Day, 1, dtPtr);
            }
            ListView1.DataSource = OneMonth;
            ListView1.DataBind();
        }
    }

现在我们有了这个:

现在,我确实想将这个月的日期“变灰”,所以在 Listview 数据绑定事件(格式化网格或列表视图的重要事件)中,然后我输入此代码

如果日期 ptr 在本月之外,我们会将链接按钮灰显。

所以,这个:

    protected void ListView1_ItemDataBound1(object sender, ListViewItemEventArgs e)
    {
        if (e.Item.ItemType == ListViewItemType.DataItem)
        {
            ListViewDataItem lvRow = e.Item as ListViewDataItem;
            for (int MyDay = 1; MyDay <= 7;MyDay++)
            {
                LinkButton LDate = lvRow.FindControl("L" + MyDay) as LinkButton;
                DateTime BoxDate =  Convert.ToDateTime(LDate.Attributes["bDate"]);
                if ( (BoxDate < dtStart) | (BoxDate > dtEnd)) 
                    LDate.BackColor = System.Drawing.Color.LightGray;

                // this sets the size for ALL squares 
                LDate.Attributes.Add("style", "float:right;height:70px;width:60px;text-align:right");
            }
        }
    }

好的,如果这是在家工作的约会,现在我们必须添加一些代码来突出显示一个正方形。

我们有这个数据table:

因此,在加载网格后,我们单击列表视图项。

那个代码是这样的:

    protected void lstEmployee_SelectedIndexChanged(object sender, EventArgs e)
    {
        int EmployeeID = 0;
        EmployeeID = Convert.ToInt32(lstEmployee.SelectedValue);
        ShowOffDays(EmployeeID);
    }

因此,我们现在需要一个例程来根据员工 ID 和给定日期显示(突出显示)table 中的任何记录。

所以这个:

    void ShowOffDays(int EmpID)
    {
        SetupDates();

        var cmdSQL = new SqlCommand(
            "SELECT * FROM AtHome WHERE EmployeeID = @EmpID " +
            "AND AtHomeDate BETWEEN @dtSTart AND @dtEnd");

        cmdSQL.Parameters.Add("@EmpID", SqlDbType.Int).Value = EmpID;
        cmdSQL.Parameters.Add("@dtStart", SqlDbType.Date).Value = dtStart;
        cmdSQL.Parameters.Add("@dtEnd", SqlDbType.Date).Value = dtEnd;

        DataTable rstAtHome = new DataTable();
        rstAtHome = MyRstP(cmdSQL);

        DateTime dtPtr = CalStart;
        for(int i = 0;i<=5;i++)
        {
            ListViewItem lvRow = ListView1.Items[i];
            for (int wDay = 1;wDay <= 7;wDay++)
            {
                if ((dtPtr >= dtStart) & (dtPtr <= dtEnd))   // only highlit this month
                {
                    LinkButton LDate = lvRow.FindControl("L" + wDay) as LinkButton;
                    DataRow[] tView = rstAtHome.Select("AtHomeDate = #" + dtPtr + "#");
                    if (tView.Length == 0)
                        // no at home date
                        LDate.BackColor = System.Drawing.Color.White;
                    else
                        // found a date - blue the square0
                        LDate.BackColor = System.Drawing.Color.LightBlue;
                }
                dtPtr = DateAndTime.DateAdd(DateInterval.Day, 1, dtPtr);
            }
        }
    }

现在,这是一些代码 - 但还不错。

所以,现在我们明白了:

好的,现在我们需要一个广场的点击事件。如果您单击一个空方块,我们会在 table 中添加一行,如果已经高亮,我们会删除它。

那么,点击事件可以是这样的:

    protected void L1_Click(object sender, EventArgs e)
    {
        LinkButton btn = sender as LinkButton;
        DateTime dtDateV = Convert.ToDateTime(btn.Attributes["bDate"]);
        int EmpID = Convert.ToInt32(lstEmployee.SelectedItem.Value);

        DataTable rstDayOff = new DataTable();
        using (var conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (var cmdSQL = new SqlCommand(
                "SELECT * FROM AtHome WHERE EmployeeID = @EmpID " +
                "AND AtHomeDate = @Date", conn))
            {
                cmdSQL.Parameters.Add("@EmpID", SqlDbType.Int).Value = EmpID;
                cmdSQL.Parameters.Add("@Date", SqlDbType.Date).Value = dtDateV;
                conn.Open();
                rstDayOff.Load(cmdSQL.ExecuteReader());
                if (rstDayOff.Rows.Count == 0 )
                {
                    // add this day off to table
                    DataRow OneDay = rstDayOff.Rows.Add();
                    OneDay["EmployeeID"] = EmpID;
                    OneDay["AtHomeDate"] = dtDateV;
                    btn.BackColor = System.Drawing.Color.LightBlue;
                }
                else
                {
                    // delete the at home day
                    rstDayOff.Rows[0].Delete();
                    btn.BackColor = System.Drawing.Color.White;
                }
                SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
                SqlCommandBuilder daU = new SqlCommandBuilder(da);
                da.Update(rstDayOff);
            }
        }
    }

不错!所以,现在你可以点击突出显示,或者 un-highlight 一天。 (它切换给定的方块)。

所以,上面应该给了你一些想法。

而我使用的两个辅助例程是获取数据table。 另一个设置日期。

这些:

    void SetupDates()
    {
        DateTime dt = DateTime.Today;

        dtStart = DateAndTime.DateSerial(DateAndTime.Year(dt), DateAndTime.Month(dt), 1);
        int DaysInMonth = DateTime.DaysInMonth(DateAndTime.Year(dt),DateAndTime.Month(dt));

        // end of month = DaysInmonth less one
        dtEnd = DateAndTime.DateAdd(DateInterval.Day, DaysInMonth - 1, dtStart);

        // now with date end/start - get display start/end (subtract day of week)

        CalStart = DateAndTime.DateAdd(DateInterval.Day, 1 - (DateAndTime.Weekday(dtStart)), dtStart);
        CalEnd = DateAndTime.DateAdd(DateInterval.Day, 41, CalStart);

    }

    DataTable MyRstP(SqlCommand cmdSQL)
    {
        DataTable rstData = new DataTable();
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (cmdSQL)
            {
            cmdSQL.Connection = conn;
            conn.Open();
            rstData.Load(cmdSQL.ExecuteReader());
            }
        }
        return rstData;
    }

所以,这是一些代码,但将每个部分分解为更小的位和大小?其实并没有那么难。

编辑:连接字符串

嗯,连接字符串一般放在web.config文件中。然而,你可以让 visual studio 为你做这件事,而且往往要容易得多。

所以,从Visual studio,转到项目->“我的项目设置”。

这样说:

那么,对于诸如欢迎信息、公司名称、使用某种税率或几乎所有应用程序都有的一系列典型设置之类的东西?

好的,您可以使用上面的设置选项卡。所以,这样说:

因此,在上面,我有 My Cool Company 名称,因此在代码中我可以引用该设置。并注意我有多个连接字符串。

使用上面的方法很好,因为如果您选择添加连接字符串,这不仅意味着整个应用程序中的一个地方,而且您可以使用连接字符串生成器来帮助您。

像这样说:

当您点击 [...] 时,您会看到:

因此,您获得了连接向导,这使得建立连接变得简单得多。

所以,现在在代码中,要获取该字符串,您可以使用:

using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))

现在,在一天结束时,如果您查看 web.config,您会看到 web.config 中的设置,但这可能是额外的工作,因此使用上面的项目设置是一个非常方便的地方,可以使用和放置您在任何典型应用程序中将拥有的所有许多设置。