Обратите внимание, что свойство SqlDataSource.ConflictDetection установлено в CompareAllValues — это гарантирует, что значения полей оригинальной записи будут переданы в качестве параметров (с использованием префикса, заданного свойством OldValuesParameterFormatString).

Большая часть работы заключается в реакции на событие DetailsView.ItemUpdated. Здесь код перехватывает все неудавшиеся обновления и явно сохраняет DetailsView в режиме редактирования.

protected void DetailsView1_ItemUpdated(object sender,
    DetailsViewUpdatedEventArgs e)
{
  if (e.AffectedRows == 0)
  {
    e.KeepInEditMode = true;
...

Но настоящий трюк заключается в повторной привязке элемента управления данными. Таким образом, исходные значения в DetailsView будут сброшены и приведены в соответствие со значениями в базе данных. Это значит, что обновление будет успешным (если пользователь попытается выполнить его опять).

...
detailsEditing.DataBind();
...

Повторная привязка сетки — это секрет, однако не весь. Чтобы поддержать значения, которые пользователь пытается применить, необходимо вручную скопировать их обратно во вновь привязанный элемент управления данными. Это несложно, но несколько утомительно.

...
// Заполнить DetailsView отредактированными значениями.
TextBox txt;
txt = (TextBox)detailsEditing.Rows[1].Cells[1].Controls[0];
txt.Text = (string)e.NewValues["CompanyName"];
txt = (TextBox)detailsEditing.Rows[2].Cells[1].Controls[0];
txt.Text = (string)e.NewValues["Phone"];
...

Теперь у вас есть элемент управления данными, который может обнаруживать неудавшиеся обновления, повторно себя привязывать и повторно вносить измененные пользователем значения. Это значит, что если пользователь щелкнет на ссылке Update (Обновить) второй раз, обновление удастся (если только запись опять не будет изменена другим пользователем).

Однако это решение все еще имеет один недостаток. Пользователь в этот момент может не иметь достаточно информации, чтобы решить, нужно ли применять обновление. Более вероятно, что он пожелает узнать, какие изменения были проведены перед тем, как перезаписать их. Один способ решения этой проблемы — перечислить текущие значения в метке или другом элементе управления. В данном примере код просто открывает элемент управления Panel, содержащий другой DetailsView:

предыдущая    следующая страница    вначало главы    оглавление

478

Hosted by uCoz