По умолчанию клик на изображении в списковой форме закрыт. Это обеспечивает стандартный PropertyEditor ASPxImagePropertyEditor.
Если добавить атрибут над полем:
[ImageEditor(ListViewImageEditorMode = ImageEditorMode. PopupPictureEdit],
то вместо фотографии появляется кнопка «Показать изображение» , а само изображение на списковой форме показано не будет.

BigPhoto01

Чтобы открыть возможность клика, надо создать свой PropertyEditor, полностью сохраняющий всю функциональность стандартного эдитора кроме атрибута [CancelClickEventPropagation] (его необходимо убрать).
Привожу код того, как это можно сделать:

[code]
[PropertyEditor(typeof(System.Drawing.Image), false)]
public class ImagePropertyEditorWithClick : WebPropertyEditor, ITestableEx, ITestable
{
// Fields
protected string imageHash;
private static List<ImageFormat> imagePossibleFormats = new List<ImageFormat>();
internal const string LocalizationGroupName = "ImagePropertyEditorWithClick";
// Methods
static ImagePropertyEditorWithClick()
{
imagePossibleFormats.Add(ImageFormat.Gif);
imagePossibleFormats.Add(ImageFormat.Jpeg);
imagePossibleFormats.Add(ImageFormat.Png);
}
public ImagePropertyEditorWithClick(Type objectType, IModelMemberViewItem model)
: base(objectType, model)
{
base.skipEditModeDataBind = true;
}
public override void BreakLinksToControl(bool unwireEventsOnly)
{
if (base.Editor != null)
{
this.PictureHolder.ImageChanged -= new EventHandler(this.PictureHolder_ImageChanged);
base.Editor.Dispose();
}
base.BreakLinksToControl(unwireEventsOnly);
}
private System.Drawing.Image ConvertToPngIfNeed(System.Drawing.Image image)
{
System.Drawing.Image image2 = image;
if ((image != null) && !imagePossibleFormats.Contains(image.RawFormat))
{
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Png);
image2 = System.Drawing.Image.FromStream(stream);
}
return image2;
}
protected override WebControl CreateEditModeControlCore()
{
return this.CreateImageControl(false);
}
private WebControl CreateImageControl(bool readOnly)
{
IPictureHolder holder;
ImageEditorMode imageEditorMode = base.Model.ImageEditorMode;
switch (imageEditorMode)
{
case ImageEditorMode.DropDownPictureEdit:
holder = new DropDownImageEdit(readOnly, false);
break;
case ImageEditorMode.PictureEdit:
{
ImageEdit edit = new ImageEdit(readOnly)
{
CustomImageHeight = this.GetCustomImageHeight(),
CustomImageWidth = this.GetCustomImageWidth(),
ImageSizeMode = base.Model.ImageSizeMode
};
holder = edit;
break;
}
case ImageEditorMode.PopupPictureEdit:
holder = new DropDownImageEdit(readOnly, true);
break;
default:
throw new ArgumentException(imageEditorMode.ToString(), "viewMode");
}
holder.ImageChanged += new EventHandler(this.PictureHolder_ImageChanged);
return (WebControl)holder;
}
protected override WebControl CreateViewModeControlCore()
{
return this.CreateImageControl(true);
}
protected override object GetControlValueCore()
{
return this.PictureHolder.Image;
}
private int GetCustomImageHeight()
{
int imageEditorCustomHeight = 0;
if (base.Model is IModelColumn)
{
imageEditorCustomHeight = base.Model.ImageEditorCustomHeight;
}
if (base.Model is IModelViewItem)
{
imageEditorCustomHeight = base.Model.ImageEditorFixedHeight;
}
return imageEditorCustomHeight;
}
private int GetCustomImageWidth()
{
return base.Model.ImageEditorFixedWidth;
}
protected override void OnCurrentObjectChanged()
{
base.OnCurrentObjectChanged();
this.RefreshImageHash();
}
protected override void OnValueStored()
{
base.OnValueStored();
this.RefreshImageHash();
}
private void PictureHolder_ImageChanged(object sender, EventArgs e)
{
if (!base.inReadValue)
{
base.EditValueChangedHandler(sender, e);
}
}
protected override void ReadEditModeValueCore()
{
this.PictureHolder.Image = this.ConvertToPngIfNeed((System.Drawing.Image)base.PropertyValue);
}
protected override void ReadViewModeValueCore()
{
((IPictureHolder)base.InplaceViewModeEditor).Image =
this.ConvertToPngIfNeed((System.Drawing.Image)base.PropertyValue);
}
private void RefreshImageHash()
{
this.imageHash = WebImageHelper.GetImageHash((System.Drawing.Image)base.PropertyValue);
}
// Properties
private IPictureHolder PictureHolder
{
get
{
return (IPictureHolder)base.Editor;
}
}
public Type RegisterControlType
{
get
{
return base.GetType();
}
}
public override bool SupportInlineEdit
{
get { return false; }
}
}
[/code]

Данный эдитор необходимо назначить требуемым полям в модели:

BigPhoto02

Эдитор готов. Теперь нужно окно для отображения фотографии. Это может быть popup-окно, встроенное в страницу:

[code]
<dx:ASPxPopupControl ID="popupControl" runat="server" ClientInstanceName="popupControl"
CloseAction="CloseButton" Height="450" Modal="True" Width="350"
PopupHorizontalAlign="WindowCenter" PopupVerticalAlign="WindowCenter" HeaderText="">

<ContentCollection>
<dx:PopupControlContentControl ID="PopupControlContentControl1" runat="server">
<img src = " " id = "imageWoker" height="100%" width="100%" alt ="No Image"/>
</dx:PopupControlContentControl>
</ContentCollection>
</dx:ASPxPopupControl>
[/code]

Добавить обработчик клиентского клика на ячейке списка (ASPxGridView). Для этого создать контроллер для объекта, клики на котором требуется обработать. Получить ASPxGridView, подписаться на событие HtmlDataCellPrepared и добавить в обработчике события  обработчик клиентского клика (например, “OnImageClick”) для требуемых ячеек с помощью строки вида:

[code]
e.Cell.Attributes.Add("onclick", string.Format("OnImageClick('{0}');",
ObjectSpace.GetKeyValue(pc).ToString()));
[/code]

Далее приведен более полный код контроллера:

[code]
public partial class PersonalContactImageViewController : ViewController
{
private void PersonalContactImageViewController_Activated(object sender, EventArgs e)
{
View.ControlsCreated += View_ControlsCreated;
}
void View_ControlsCreated(object sender, EventArgs e)
{
ASPxGridListEditor listEditor = ((ListView)View).Editor as ASPxGridListEditor;
if (listEditor != null)
{
ASPxGridView grid = listEditor.Control as ASPxGridView;
if (grid != null)
{
grid.HtmlDataCellPrepared -= grid_HtmlDataCellPrepared;
grid.HtmlDataCellPrepared += grid_HtmlDataCellPrepared;
grid.ClientInstanceName = "personalContact";
grid.CustomCallback += grid_CustomCallback;
grid.SelectionChanged += grid_SelectionChanged;
}
}
}
void grid_HtmlDataCellPrepared(object sender, ASPxGridViewTableDataCellEventArgs e)
{
if (e.CellValue == null)
return;
if (e.DataColumn.FieldName == "Person.FullName")
fio = e.CellValue.ToString();
if (e.DataColumn.FieldName == "Email")
mail = e.CellValue.ToString();
Image img = e.CellValue as Image;
if (img != null)
{
CriteriaOperator criteria = CriteriaOperator.Parse("Person.FullName = ?", fio);
PersonalContact pc = ObjectSpace.FindObject<PersonalContact>(criteria);
if (pc != null)
e.Cell.Attributes.Add("onclick", string.Format("OnImageClick('{0}');",
ObjectSpace.GetKeyValue(pc).ToString()));
}
}
}
[/code]

Затем требуется добавить реализацию обработчика «OnImageClick» в виде javascript на странице:
[code]
<head id="Head1" runat="server">
………….
<script language="javascript" type="text/javascript">
function OnImageClick(personID)
{
// Получаем элемент страницы с идентификатором «imageWoker»
// Это элемент для отображения картинок, в ранее созданном popup окне
// (см. выше)
var imggg = document.getElementById('imageWoker');
// Задаем картинку
// Это может путь на картинку из директории проекта
// Или же картинку можно получать непосредственно из БД
// Ниже картинка грузится из БД
// 'GetImage.ashx – спициальный хэндлер, который возвращает ответом картинку
// (см. реализацию ниже)
imggg.src = 'GetImage.ashx?personID=' + personID;
// Данная строка нужна для обратной связи с сервером
// Вызывает отработку на сервере события «CustomCallback» ASPxGridView
// Может использоваться, например, для запрета открытия карточной формы
// personalContact – клиентское имя ASPxGridView установленное в обработчике
// View_ControlsCreated для требуемого грида (см. выше)
personalContact.PerformCallback("image");
// Отображение окна с картинкой
popupControl.Show();
}
</script>
</head>
[/code]

И создадим класс для отображения фотографии:

[code]
/// <summary>
/// Класс для отображения картинки
/// </summary>
public class GetImage : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string imageID;
Byte[] imageBytes;
imageID = context.Request.QueryString["personID"];
// PersonImage – вспомогательный класс, который получает картинку из БД
// Его функция GetImage воьзвращает картинку в виде массива байтов.
// Каким способом реализовать GetImage – на усмотрения разработчика
imageBytes = PersonImage.GetImage(imageID);
context.Response.ContentType = "image/jpeg";
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.BufferOutput = false;
context.Response.OutputStream.Write(imageBytes, 0, imageBytes.Length);
}
public bool IsReusable
{
get { return false; }
}
}
[/code]

Данные действия приведут вот к такому результату:

BigPhoto03