powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Хендлер вызывается много раз
12 сообщений из 12, страница 1 из 1
Хендлер вызывается много раз
    #38880001
ughunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смысл вот в чем:
Динамически создается несколько кнопок. На каждую вешается хендлер. Если например разместили 2 кнопки - 2 раза вызовется. 3 - 3 раза и тд. Не могу понять - в чем же дело? Имена у кнопок разные - остальное 1:1

вот код:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
public class frmMAin : Form
{
	private const string _myApp = "c:\\FC.2010\\FC.FeedBack\\FC.FeedBack.Test\\bin\\Debug\\";
	public frmMAin()
	{
		InitializeComponent();
		PluginManager.SetPluginPath(_myApp, cn);
		List<BarItem> buttons = PluginManager.AddItems(this, "АРМ");
		if (buttons != null)
		{
			foreach (DevExpress.XtraBars.BarButtonItem Button in buttons)
			{
				Button.ItemClick += new System.EventHandler(Button_ItemClick);
			}
		}
	}
	private void Button_ItemClick(object sender, ItemClickEventArgs e)
	{
		if (e.Item.Tag as Form != null)
		{
			Form frm = (Form) e.Item.Tag;
			frm.MdiParent = this;
			frm.Tag = Guid.NewGuid.ToString();
			frm.Show();
		}
		else
		{
			System.Guid _guid = new Guid(e.Item.Tag.ToString());
			foreach (Plugin pl in PluginManager.GetList.Items)
			{
				if (pl.GUID == _guid)
				{
					if (pl.Type != PluginType.From)
					{
						pl.MainForm.MdiParent = this;
						pl.MainForm.Tag = Guid.NewGuid.ToString();
						pl.MainForm.Show(this);
					}
					else if (pl.Type == PluginType.From)
					{
						pl.MainForm.Tag = Guid.NewGuid.ToString();
						DialogResult dr = pl.MainForm.ShowDialog(this);
					}
				}
			}
		}
		
	}
}
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38880015
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ughunter,

возможно делегат в классе, имеет 1 единственный экземпляр для всех 3 кнопок
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38880037
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
if (Button.ItemClick == null)
{
   Button.ItemClick += new System.EventHandler(Button_ItemClick);
}
else
{
// вот тут можно поймать второй раз вызова, когда уже есть обработчик, а кто-то еще раз его добавляет
}
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38880280
ughunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
похоже это как-то связано с тем, что передается (создается) не новый объект - а ссылка.
отсюда вопрос:

Код: c#
1.
public partial class mainForm : Form {}



далее

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
public struct PluginActionItem
    {
        public Locations Location;
        public LocationDescriptions LocationDescription;
        public Items Item;
        public sMainForm Form;
    }

public class sMainForm
    {
        public Form form;
        public PluginType pluginType;
    }

BarButtonItem barButtonItem = new BarButtonItem()
            {
                Caption = @"Обратная связь",
                Glyph = (Image)Properties.Resources.Icon32x32,
                LargeGlyph = (Image)Properties.Resources.Icon32x32,
                Name = "BarButtonItem_" + number,
                Tag = new sMainForm()
                {
                    [color=red]Form = mainForm,[/color]
                    pluginType = pluginType
                }
            };

[color=orange]Dim form As Form = mf.Form[/color]

            If mf.pluginType <> PluginType.From Then
                Form.MdiParent = Me
                Form.Tag = Guid.NewGuid.ToString
                Try
                    Form.Show()
Catch ex As Exception
                    XtraMessageBox.Show(ex.Message)
                End Try
End if



после закрытия формы попадаем на эксепшен. доступ к уничтоженному объекту ...
Как (выделено оранжевый) передать не ссылку на объект - а создать новый ? Никак понять не могу.
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38880282
ughunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Dim form As Form = mf.Form

            If mf.pluginType <> PluginType.From Then
                Form.MdiParent = Me
                Form.Tag = Guid.NewGuid.ToString
                Try
                    Form.Show()
Catch ex As Exception
                    XtraMessageBox.Show(ex.Message)
                End Try
End if



Этот кусочек в хэндлере нажатия на кнопку основной формы.
Уточнение: при первом нажатии - все ок - при повторном - эксепшен
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38880444
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ughunterпохоже это как-то связано с тем, что передается (создается) не новый объект - а ссылка.
отсюда вопрос:
....
Как (выделено оранжевый) передать не ссылку на объект - а создать новый ? Никак понять не могу.
Создавать новый обьект нужно только тогда, когда в нем будут храниться другие данные.
Если для тех же операциий и отображения тех же данных вы думаете как создать новый обьект - это ошибка в дизайне.
Пересмотрите сначала порядок действий и "кто кого" ...
Если вы это не решите - а заткнете баг какой-нибудь пробкой - то баг вылезет где-то еще, и будет уже трудноулавливаемый...
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38881262
ughunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Именно в нем будут хранится новые данные. В случае если форма вызывается как модальное окно - ее закрытие можно контролировать. В остальных случаях всем рулит оконный менеджер и он принудительно вызывает dispose объекта. А поскольку ссылка на него - вот эксепшен и вылазит. Вернемся с чего начали - как же создать новый? Единственно что приходит на ум - вывести конструктор класса формы в паблик... Но тогда встает другой вопрос - если форм много то как указать какой именно использовать конструктор в хендлере нажатия на кнопку?
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38881438
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ughunter,

Вам надо разобраться с отличиями данных от кода.
Код "нигде не хранится" - не копируется вместе с данными и память под него не выделяется, и не бывает двух разных "экземпляров кода".
Делегат - это просто защищенная ссылка на некий код. Оставим в стороне реализацию - для простототы.

Когда вы подписываетесь (+= ) на эвент - вы просто добавляете адрес функции (делегат) в коллекцию, которая будет использована при "поднятии" эвента.

Очевидно, что если обработчик вызывается несколько раз - это значит, он несколько раз был добавлен в коллекцию.

Поставьте брейкпойнт на += - и ловите, откуда происходит переподписка....
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38881543
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну Вы сказали, "на код память не выделяется" :) выделяется, просто в сегменте кода :)
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38881708
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesну Вы сказали, "на код память не выделяется" :) выделяется, просто в сегменте кода :)

Я в кавычках написал.
Это, кстати, довольно обычное заблуждение - когда предлагаешь весь код держать в соответственном классе, а таких обьектов коллекция - мне приходилось пару раз спорить, что место в памяти много раз будут занимать только данные...
:-)
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38882453
ughunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D129,

Согласен с Вами по всем пунктам. Обработчик действительно записан в коллекцию несколько раз, одна ведь при нажатии кнопки он вызывается один раз? А ведет себя как будто на кнопку нажали (2,3 ...) раза
...
Рейтинг: 0 / 0
Хендлер вызывается много раз
    #38882660
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ughunter,

Вот этот код -

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
List<BarItem> buttons = PluginManager.AddItems(this, "АРМ");
		if (buttons != null)
		{
			foreach (DevExpress.XtraBars.BarButtonItem Button in buttons)
			{
				Button.ItemClick += new System.EventHandler(Button_ItemClick);
			}
		}



Вызывает наибольшее подозрение.
Кнопки, чтобы рисоваться на форме, должны быть в коллекции контролов формы .Controls
И они там есть - раз вы их видите.
А хендлер вы добавляте к кнопкам из коллекции buttons. Отсюда вопрос - те же самые ли это кнопки?
Что делает PluginManager.AddItems(this, "АРМ"); ?

Излишне, и не вполне правильно использовать еще одну коллекцию, назначение которой (перебор элементов коллекции) может выполнить уже существующая (.Controls)....
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Хендлер вызывается много раз
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]