Changing hardcoded dates to dynamic

2019-08-08 21:07发布

问题:

I'm working on some old code (not mine) which, unfortunately, has a lot of hard-coded code in it which has been causing issues that I'm now trying to fix. Here's my issue right now:

There is a gridview with 14 columns representing two weeks. The first day is either a Monday or Sunday depending on a boolean in the code which checks which "type" a user is.

Now, all days are layed out like so (this is for Sunday):

    <asp:TemplateField HeaderText="SUN">
        <footertemplate>
            <asp:Label ID="lblD1F" runat="server" ForeColor="white" Width="35px" Text="<%# GetTotal(0).ToString() %>" />
        </footertemplate>
        <headertemplate>
            <asp:Label ID="lblD1H" runat="server" CssClass="hdr_Day" Text="SUN"></asp:Label><br />
            <asp:Label ID="lblD1D" runat="server" CssClass="hdr_Date" Text='<%# _displayDate.ToString("MM/dd") %>'></asp:Label>                
        </headertemplate>
        <itemtemplate>
            <anthem:TextBox id="tbDay1" 
                            runat="server" 
                            Text='<%# Bind("Day1") %>'  
                            CssClass="tbWeekEnd" 
                            AutoCallBack="true" />
            <asp:Label ID="lblDay1" runat="server" Visible="false" Text='<%# Bind("Day1") %>'></asp:Label>

        </itemtemplate>
        <itemstyle cssclass="cell_weekend" />
    </asp:TemplateField>

So 14 days set-up like above result in below:

Now, I was trying to make it so it would start on Sunday OR Monday, based on the user. I pretty much hard-coded new strings over top the old ones, which is just starting to cause more problems. First I made two constant strings:

String[] userADays = new String[] { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
String[] userBDays = new String[] { "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" };

protected void gvMasterProjects_RowDataBound(object sender, GridViewRowEventArgs e)
{

    //This if/else statement overrides the hard coded date headers in the timeEntry aspx files since the days were hardcoded in.
    //Populates the cells w/ the data from one of two arrays depending if the user is A or B.
    if (e.Row.RowType == DataControlRowType.Header)
    {
        e.Row.CssClass = "HeaderStyle";
        if (isUserB == false)
        {
            for (int i = 9; i < 23; i++)
            {
                e.Row.Cells[i].Font.Size = 10;
                e.Row.Cells[i].Text = userADays[i - 9] + "\n" + " " + _displayDate.AddDays(i-9).ToString("MM/dd") + " ";

            }
        }

        else
        {
            for (int i = 9; i < 23; i++)
            {
                e.Row.Cells[i].Font.Size = 10;
                e.Row.Cells[i].Text = UserBDays[i - 9] + "\n" + " " + _displayDate.AddDays(i - 9).ToString("MM/dd") + " ";

            }
        }
    }

Here's the gridview stuff in the .aspx file:

<anthem:GridView 
    ID="gvMasterProjects" 

    runat="server" 
    AutoGenerateColumns="false" 
    ShowFooter="true" 
    OnRowDataBound="gvMasterProjects_RowDataBound" 
    AllowPaging="false"
    EnableViewState="true" 
    HorizontalAlign="Center"
    AlternatingRowStyle-CssClass="AlternatingRowStyle" 
    RowStyle-CssClass="RowStyle" 
    HeaderStyle-CssClass="HeaderStyle" style="margin-left: 71px">

I really want to do away with this hard-coding. There's got to be an easier way to have these dates loaded w/o doing what's being done right now. Any help would be greatly appreciated.

Edit: Attempted the answers below, which work except that there are many "UpdateAfterCallBack" lines that are executed which result in the dates being reverted to the hardcoded ones in .aspx. Is there an easy way to do this in .aspx?

回答1:

Have you considered just having a "buffer" Day in there so that if the user is of the type you want you add one day onto the start day?

What this would do is create a buffer which is 0 by default and 1 if a specific type of user. This then gets added in and you have your date.

protected void gvMasterProjects_RowDataBound(object sender, GridViewRowEventArgs  e)
{
    //This if/else statement overrides the hard coded date headers in the timeEntry aspx files since the days were hardcoded in.
    //Populates the cells w/ the data from one of two arrays depending if the user is A or B.
    if (e.Row.RowType == DataControlRowType.Header)
    {
        e.Row.CssClass = "HeaderStyle";
        var bufferDay = 0; // Starts on sunday.
        if (isUserB)
        {
            bufferDay = 1; // Starts on Monday.
        }
        for (int i = 9; i < 23; i++)
        {
            e.Row.Cells[i].Font.Size = 10;
            var dayOfWeek = _displayDate.AddDays(i - 9 + bufferDay);
            e.Row.Cells[i].Text = dayOfWeek.ToString("ddd") + "\n" + " " + dayOfWeek.ToString("MM/dd") + " ";
        }        
    }
}

Per your edit: What happens if you edit the .aspx like this so that it pulls the day text based on the date provided? I'm not sure if you'd have to add in a reference to _displayDate for HeaderText or not (it's been a while since I messed with aspx). I'm not sure that the data would even be bound at the time you call it to sub in HeaderText.

  <asp:TemplateField HeaderText="SUN">
    <footertemplate>
        <asp:Label ID="lblD1F" runat="server" ForeColor="white" Width="35px" Text="<%# GetTotal(0).ToString() %>" />
    </footertemplate>
    <headertemplate>
        <asp:Label ID="lblD1H" runat="server" CssClass="hdr_Day" Text='<%# _displayDate.ToString("mmm") %>'></asp:Label><br />
        <asp:Label ID="lblD1D" runat="server" CssClass="hdr_Date" Text='<%# _displayDate.ToString("MM/dd") %>'></asp:Label>                
    </headertemplate>
    <itemtemplate>
        <anthem:TextBox id="tbDay1" 
                        runat="server" 
                        Text='<%# Bind("Day1") %>'  
                        CssClass="tbWeekEnd" 
                        AutoCallBack="true" />
        <asp:Label ID="lblDay1" runat="server" Visible="false" Text='<%# Bind("Day1") %>'></asp:Label>

    </itemtemplate>
    <itemstyle cssclass="cell_weekend" />
</asp:TemplateField>

I personally would even look into a method to automate the TemplateFields. It looks like you have a lot of repeated code, that you could create from a class like what is mentioned in the other answer on this thread. But try the above to see if that fixes your update issue.



回答2:

Here is a SO thread that explains setting the initial day of the week. It involves creating a "custom culture." Note that the DateTimeFormatInfo class has a FirstDayOfWeek property. I suppose you can create 2 instances, each starting with a different day. Perhaps a custom culture is a bit much, in any case have a FirstWeekDay property somewhere that your code sets.

Once set, look at DateTime formatting so you can output "SUN", "MON", etc. by iterating through the DayOfWeek enumeration and outputting it in your desired format

All the above should be encapsulated in a class so it's just a matter of calling simple methods or properties. It will really clean up the coding at the "level" you show; and it's reusable of course. But again, I'm imagining an instance for each first-day-of-the-week, but I suspect that much of the code could be static.

Finally, this is cool.