Как изменить Bind ("MyValue") в asp.net - PullRequest
2 голосов
/ 06 февраля 2009

У меня болит голова из-за значений времени и нескольких часовых поясов. Я сохраняю новые значения DateTime во времени UTC, но у меня возникает проблема, когда я пытаюсь изменить их с помощью LinqDataSource и GridView.

Я могу легко показать правильное время в

<ItemTemplate>
    <asp:Label ID="Label1" runat="server" Text='<%# TimeManager.ToLocalTime((DateTime)Eval("OrderDate")) %>' />
</ItemTemplate>

В настоящее время это добавит 1 час к времени UTC, хранящемуся в БД.

Однако привязка к источнику нелегка. Привязка ("OrderDate") не может быть изменена, как TimeManager.ToGlobalTime ((DateTime) Bind ("OrderDate")).

Я думал об использовании события OnUpdating LinqDataSource для обновления значения до глобального времени, но что, если пользователь изменил другие поля, а не поле даты? Каждый раз, когда он обновляет запись, значение времени будет меньше на один час.

Сравнение старых и новых значений также не очень хорошо, потому что пользователь может изменять часть даты даты и времени, а не время, на которое влияют часовые пояса?

Если бы у меня был способ показать местное время во всех состояниях gridview, я мог бы легко использовать OnUpdating из LinqDataSource.

Пожалуйста, поделитесь своими мыслями ...

Ответы [ 2 ]

3 голосов
/ 06 февраля 2009

Рассматривали ли вы изменения в вашей модели? Давайте предположим, что имя объекта, к которому вы привязываете, - 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 () определен правильно)

2 голосов
/ 06 февраля 2009

То, как я обрабатывал подобные вещи в прошлом, - это также использовать Eval в EditItemTemplate. Позвольте пользователю редактировать элемент по местному времени. Затем добавьте обработчик OnItemUpdating для вида сетки и добавьте извлечь значение связанного текстового поля, преобразовать его в глобальное время и добавить его в словарь новых значений. Привязать исходное значение в (в глобальном времени) к скрытому полю в том же шаблоне, который заполнит словарь старых значений правильным старым временем. Вы захотите сделать то же самое при вставке в OnItemInserting, хотя вам явно не нужно старое значение (так как его нет).

РЕДАКТИРОВАТЬ : Обычно я делаю свои обновления в DetailsView, а не в GridView, таким образом, ItemUpdating / Inserting вместо RowUpdating / Inserting. Пример кода ниже - в этом примере используется пара раскрывающихся списков, которые позволяют пользователю указать местоположение (выбрать здание и местоположение в здании, но на самом деле оно отображает только местоположение в базе данных). На серверной части он назначает начальные значения раскрывающимся спискам в OnPreRender (не показан) и извлекает значение поля базы данных LocationID из раскрывающегося списка местоположений в ItemUpdating / Inserting (показано обновление). DetailsView помещается в UpdatePanel, и заполнение раскрывающегося списка Location выполняется при изменении раскрывающегося списка здания. Обратите внимание, что, поскольку я обновляю элемент (в любом случае вызываю оператор update), мне все равно, будет ли поле LocationID перезаписываться при обновлении тем же значением, поэтому я не буду беспокоиться о сохранении старого значения на странице.

<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>

Codebehind:

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;
}
...