I could not reproduce your issue using this code:
<%@ Page Language="vb" AutoEventWireup="false" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim animals As New List(Of Animal)
animals.Add(New Animal With {.AnimalName = "JSOP"})
animals.Add(New Animal With {.AnimalName = "Unicorn"})
dgSample.EditItemIndex = 0
dgSample.DataSource = animals
dgSample.DataBind()
End Sub
Public Class Animal
Public Property AnimalName As String
End Class
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test ReadOnly</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataGrid runat="server" ID="dgSample" AutoGenerateColumns="false">
<Columns>
<asp:TemplateColumn HeaderText="Animal Name">
<ItemTemplate>
Viewing:
<asp:TextBox runat="server" ReadOnly="true"
Text='<%# DataBinder.Eval(Container.DataItem, "AnimalName")%>' />
</ItemTemplate>
<EditItemTemplate>
Editing:
<asp:TextBox runat="server" ReadOnly="true"
Text='<%# DataBinder.Eval(Container.DataItem, "AnimalName")%>' />
</EditItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</div>
</form>
</body>
</html>
What browser are you using? Perhaps when you click BACKSPACE, you are navigating back to a previous page (that is a common scenario in which you'd get "web page expired")? You can also get "web page expired" when you have done a postback (e.g., after pressing ENTER and activating the default button on the page) and you try to refresh the page. Does the issue occur when you use the DELETE key instead? Could there be some JavaScript that is detecting the BACKSPACE key and causing the browser to navigate to the previous URL? Some other things to check: are you sure ReadOnly is set to "true" in the EditItemTemplate (just to double check) and do you have AutoPostBack set to "true" (that could cause some issues)?