Question

I just haven't been able to find the solution after searching existing questions.

Basically, I have a Details View with Editing enabled. It is bound to a LINQDataSource. One of the fields is a SQL time, which comes into ASP.NET as a TimeSpan. I want a 2-way binding. I already have functions that convert between String and TimeSpan for my purposes.

But here's my conundrum. I feel like I need one Text= expression to populate the text box when editing begins,

<EditItemTemplate>
    <asp:TextBox ID="TextBox1" runat="server" Text='<%# TimeSpanToString(Eval("Time")) %>'></asp:TextBox>
</EditItemTemplate>

but at the same time, a different Text= expression to specify the TimeSpan value to write back to the database on an Update; something like this:

<EditItemTemplate>
    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Time", StringToTimespan(TextBox1.Text) %>'></asp:TextBox>
</EditItemTemplate>

As you can see, I'm very unsure of the syntax to use in the Eval and Bind expressions in the first place, but hopefully I have explained my problem successfully. There can only be one Text= expression, so obviously something quite different needs to be done here in order to allow the two conversions to take place during data binding and updating.

Thanks! Sandra

Trying solution from @jadarnel23:

For the ItemTemplate, TimeSpanToTimeString(Eval("Time")) works perfectly. And also the ItemUpdating function works perfectly - user can enter e.g. 1:30 pm, and it is accepted.

The only problem left is the EditTemplate.

Bind("Time") works, but does not present the user with nicely formatted time.

TimeSpanToString(Eval("Time")) does not work, as you said, because it doesn't create the NewValues entry to work with in ItemUpdating.

And the one that should be the winner, TimeSpanToString(Bind("Time")), actually throws an error on binding "Compiler Error Message: BC30451: 'Bind' is not declared. It may be inaccessible due to its protection level." It looks like I need to elaborate on Bind so that my function can see it, but how? Thanks, this is really close!!

Était-ce utile?

La solution

Since you cannot call the Bind "method" from within another public method in your markup (like you can do with Eval), it looks like you are stuck doing a normal "Bind" in the EditItemTemplate:

<EditItemTemplate>
    <asp:TextBox ID="TextBox1" runat="server" 
        Text='<%# Bind("Time") %>'>
    </asp:TextBox>
</EditItemTemplate>

Note: you need to do a Bind, because that will make it show up in your ItemUpdating event later, to save it to the database

Then update it for display purposes as soon as the DetailsView is databound (make sure it's also in Edit Mode):

protected void yourDetailsView_DataBound(object sender, EventArgs e)
{
    if (yourDetailsView.CurrentMode == DetailsViewMode.Edit)
    {
        TextBox timeTextBox = (TextBox)yourDetailsView.FindControl("TextBox1");
        timeTextBox.Text = TimeSpanToString(timeTextBox.Text);
    }
}

Then, you can handle the ItemUpdating event, and manipulate the value of "Time" prior to saving it to the database:

protected void yourDetailsView_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
    String newTime = e.NewValues["Time"].ToString();
    e.NewValues["Time"] = StringToTimespan(newTime);
}

Notice you can extract the user-entered values from the DetailsViewUpdateEventArgs.NewValues collection

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top