2014-01-23 2 views
0

Три ImageButtons ниже добавлены к панели (pBreakfast) в коде страницы только:Event Handler Остановка работать после Dispose

ImageButton ibSR = new ImageButton(); 
ibSR.ID = "ibStickyRoll"; 
ibSR.ImageUrl = "/images/Breakfast.gif"; 
ibSR.Click += new ImageClickEventHandler(ImageButton_Click); 
pBreakfast.Controls.Add(ibSR); 

ImageButton ibD = new ImageButton(); 
ibD.ID = "ibDoughnut"; 
ibD.ImageUrl = "/images/Breakfast.gif"; 
ibD.Click += new ImageClickEventHandler(ImageButton_Click); 
pBreakfast.Controls.Add(ibD); 
ibD.Dispose(); 

using(ImageButton ibC = new ImageButton()){ 
    ibC.ID = "ibCrepe"; 
    ibC.ImageUrl = "/images/Breakfast.gif"; 
    ibC.Click += new ImageClickEventHandler(ImageButton_Click); 
    pBreakfast.Controls.Add(ibC); 
} 

Я ожидал, что либо все три будет работать, или, возможно, захороненные ImageButtons будут генерировать ошибку или просто не появляются. Но все, что происходит, все три появляются и не вызывают никаких ошибок, но обработчик событий никогда не срабатывает для выбранных ImageButtons.

Почему утилизация приводит к тому, что уходит только соединитель для обработки событий?

Я динамически добавляю TableRow и TableCell в таблицу на этой же странице и помещая ImageButtons в одну ячейку каждой строки. Я использую «использование» с TableRow и TableCell без каких-либо проблем. Кажется, что проблема не связана с внешними (TableRow & TableCell) объектами; до тех пор, пока я никогда не удаляю динамические ImageButtons, обработчик событий загорается ОК при нажатии.

В порядке ли это, что вы никогда не выбрали ImageButtons? Я принял совет StackOverflow и попытался использовать using() для всех моих одноразовых объектов - так что это действительно подталкивает меня.

Спасибо!

ответ

1

Только удалите объект после того, как все будет полностью выполнено с ним. Попытка сделать что-либо с объектом после его удаления приведет к неопределенному поведению. Подумайте, как освободить память.

К счастью, формы Windows располагают этими объектами для вас, когда вы закрываете форму. Единственный случай, который вам нужно будет использовать в своем коде, - это удалить объекты из формы.

Посмотрите на файл .Designer.cs, и вы увидите метод формы в Dispose():

/// <summary> 
/// Clean up any resources being used. 
/// </summary> 
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
protected override void Dispose(bool disposing) 
{ 
    if (disposing && (components != null)) 
    { 
     components.Dispose(); 
    } 
    base.Dispose(disposing); 
} 

components.Dispose() рекурсивно очистить все компоненты на форме, в том числе в панели.

+0

Спасибо, что ответ, Моби. Я не могу не думать, что есть нечто большее, чем это. Действительно ли dispose() происходит сразу, хотя есть ссылка на него в pBreakfast? Я думал, что новый ImageButton в pBreakfast.controls теперь принадлежит pBreakfast, и утилита не произойдет, пока pBreakfast не будет очищен. Это довольно запутанно для меня. Почему ImageButton является одноразовым, если я не должен избавляться от него после .Add()? Кроме того, для этого решения нет конструктора.cs (по крайней мере, я не смог его найти), я использую компиляцию по запросу на сервере. : ^) –

+0

Утилизация не происходит немедленно. Это происходит только тогда, когда что-то вызывает Dispose() явно. Вы правы, когда говорите, что новый ImageButton в pBreakfast.controls теперь принадлежит pBreakfast, и утилита не будет выполняться до тех пор, пока pBreakfast не будет очищен. Это именно то, что вы хотите. После того, как что-то вызывает Dispose() в ImageButton, ImageButton бесполезен. мертвый. капут. Вы не хотите создавать ImageButton, отдавать его pBreakfast, а затем уничтожать его! ImageButton является одноразовым, так что его можно очистить после того, как форма полностью исчезнет. –

+0

Кроме того, я doof и пропустил, что это был ASP.NET, а не WinForms. Извини за это. Но он по-прежнему стоит: не удаляйте объект, пока кто-то его использует. –