我对时间值和多个时区感到头痛。 我正在以UTC时间存储新的DateTime值,但是当我尝试使用LinqDataSource和GridView修改它们时,我遇到了问题。
我可以轻松地在
中显示正确的时间<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# TimeManager.ToLocalTime((DateTime)Eval("OrderDate")) %>' />
</ItemTemplate>
目前,这将为存储在DB中的UTC时间增加1小时。
然而,绑定回源并不容易。绑定(“OrderDate”)不能像TimeManager.ToGlobalTime((DateTime)Bind(“OrderDate”))那样进行修改。
我正在考虑使用LinqDataSource的OnUpdating事件将值更新为全局时间,但是如果用户修改了其他字段而不是日期字段呢?每次他更新记录时间值都会小一小时。
比较旧值和新值也不是很好,因为用户可以修改日期时间的日期部分而不是时间,这会受到时区的影响吗?
如果我有办法在gridview的所有状态中显示本地时间,那么我可以轻松使用LinqDataSource的OnUpdating。
请分享您的想法...
答案 0 :(得分:3)
您是否考虑过更改模型?假设您绑定的对象的名称是CustomerOrder。您可以将以下类添加到项目中(与Linq对象在同一名称空间中):
public partial class CustomerOrder
{
public DateTime LocalOrderDate
{
get { return TimeManager.ToLocalTime(OrderDate); }
set { OrderDate = TimeManager.ToUTCTime(value); }
}
}
现在不是绑定到OrderDate,而是绑定到LocalOrderDate。这将自动将UTC /本地时间转换为OrderDate。
(注意:我假设您有TimeManager.ToLocalTime()和TimeManager。正确定义了ToUTCTime())
答案 1 :(得分:2)
我过去处理此类事情的方式是在EditItemTemplate中使用Eval。让用户在本地时间编辑项目。然后为gridview添加OnItemUpdating处理程序,并添加提取相关文本框的值,将其转换为全局时间,并将其添加到新值字典中。将原始值(在全局时间内)绑定到同一模板中的隐藏字段,该字段将使用正确的旧时间填充旧值字典。你想在插入OnItemInserting时做同样的事情,虽然你显然不需要旧的值(因为没有一个)。
编辑:通常我在DetailsView而不是GridView上进行更新,因此使用ItemUpdating / Inserting而不是RowUpdating / Inserting。下面的示例代码 - 此示例使用一对下拉列表,允许用户指定一个位置(选择建筑物和建筑物中的位置,但它实际上只映射数据库中的位置)。在后端,它为OnPreRender中的下拉列表分配初始值(未显示),并从ItemUpdating / Inserting(显示更新)的位置下拉列表中提取LocationID数据库字段值。 DetailsView包含在UpdatePanel中,当构建下拉选择更改时,将完成位置下拉列表的填充。请注意,因为我正在更新项目(无论如何都会导致更新语句),我不关心LocationID字段是否在更新时覆盖了相同的值,因此我不打算在页面上保留旧值。 / p>
<asp:TemplateField HeaderText="Location:" SortExpression="LocationId">
<EditItemTemplate>
<asp:DropDownList runat="server" ID="buildingDropDownList"
DataSourceID="buildingDataSource"
DataTextField="name"
DataValueField="abbreviation"
OnSelectedIndexChanged=
"buildingDropDownList_SelectedIndexChanged"
AutoPostBack="true" />
<asp:DropDownList runat="server" ID="locationDropDownList"
DataSourceID="locationsDataSource"
DataTextField="Name"
DataValueField="ID">
</asp:DropDownList>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList runat="server" ID="buildingDropDownList"
DataSourceID="buildingDataSource"
DataTextField="name"
DataValueField="abbreviation"
OnSelectedIndexChanged=
"buildingDropDownList_SelectedIndexChanged"
AutoPostBack="true"
AppendDataBoundItems="true">
<asp:ListItem Text="Select Building" Value="" />
</asp:DropDownList>
<asp:DropDownList runat="server" ID="locationDropDownList"
DataSourceID="locationsDataSource"
DataTextField="Name"
DataValueField="ID"
AppendDataBoundItems="true">
<asp:ListItem Text="Not installed" Value="" />
</asp:DropDownList>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="locationLabel" runat="server"\
Text='<%# Eval("LocationID") == null
? ""
: Eval("Location.Name") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
代码隐藏:
void editPrinterDetailsView_ItemUpdating( object sender,
DetailsViewUpdateEventArgs e )
{
// Use a helper method to find the dropdown inside the details view
// and get the selected value.
string locationID = ControlHelper
.GetDropDownValue( editPrinterDetailsView,
"locationDropDownList" );
if (locationID == string.Empty)
{
locationID = null;
}
if (e.NewValues.Contains( "LocationID" ))
{
e.NewValues["LocationID"] = locationID;
}
else
{
e.NewValues.Add( "LocationID", locationID );
}
e.OldValues["LocationID"] = -1;
}