MasterMan342
|
|
« : 09-03-2012 20:08 » |
|
Добрый вечер уважаемые формучане! в общем суть моей проблемы следующая: Сделал контрол, и пользовательское событие... При нажатии на участок контрола происходит его перерисовка, и вызов данного события... При этом, вызов обработчика события находится прямо в конце метода Paint, то-есть после полной отрисовки всех частей... Все бы хорошо, но, не работает как надо! при использовании контрола событие запускается правильно, обработчик запускает правильно, если в нем нет цикла ... я уже не знаю что с этим делать! Мне надо как-то определить момент, когда контрол полностью завершил открисовку!? В противном случае, малейшая задержка (вроде цикла), и контрол отключается (красный перекрест по всему контролу...)
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 09-03-2012 20:31 » |
|
MasterMan342, попробуйте рисовать не в GUI-событии, а асинхронно. Не знаю, что для этого есть в C#, а в Win32 API для этого используется InvalidateRect и событие onPaint (WM_PAINT).
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zubr
Гость
|
|
« Ответ #2 : 09-03-2012 22:51 » |
|
А что делает цикл в Paint? Что то последовательно отрисовывает? Тогда изначально подход неверен.
|
|
|
Записан
|
|
|
|
MasterMan342
|
|
« Ответ #3 : 12-03-2012 14:31 » |
|
А что делает цикл в Paint? Что то последовательно отрисовывает? Тогда изначально подход неверен.
Цикл не в пайнте а в событии... т.е. при вызове события с циклом внутри процесс прорисовки приостанавливается! почему ?! вызовобработчика положен в самый конец метода Paint.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #4 : 12-03-2012 15:03 » |
|
MasterMan342, потому что событие обрабатывается не асинхронно. Событие - это лишь замаскированный вызов процедуры. Т.е. представь, что ты в конец Paint вписал вызов процедуры с циклом.
Чтобы развязать эту связь, нужно в обработчике события запускать асинхронную задачу. Правда, потом придётся следить, чтобы параллельные асинхронные задачи не накладывались друг на друга во время исполнения или как-то иначе их синхронизировать.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
MasterMan342
|
|
« Ответ #5 : 13-03-2012 08:15 » |
|
MasterMan342, потому что событие обрабатывается не асинхронно. Событие - это лишь замаскированный вызов процедуры. Т.е. представь, что ты в конец Paint вписал вызов процедуры с циклом.
Чтобы развязать эту связь, нужно в обработчике события запускать асинхронную задачу. Правда, потом придётся следить, чтобы параллельные асинхронные задачи не накладывались друг на друга во время исполнения или как-то иначе их синхронизировать.
Я переместил вызов события в событие MuseClick, и событие Paint заменил переопределенным OnPaint. сейчас без цикла обработчик запускается нормально, но с циклом - выдает ошибку, похоже, сразу после выхода из обработчика. название ошибки точно не помню . и что странно, если в цикле находится какая-нить процедура, то цикт выполняется 1 раз, и событие завершается!
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #6 : 13-03-2012 08:16 » |
|
Код в студию
|
|
|
Записан
|
|
|
|
MasterMan342
|
|
« Ответ #7 : 13-03-2012 17:36 » |
|
Код в студию
Ну Посмотри))) не ругай больно сильно, я только учусь! http://ifolder.ru/29272140Да и кстати, ошибка которую студия выдает: Не удалось найти распознаваемые цифры.
|
|
« Последнее редактирование: 13-03-2012 17:38 от MasterMan342 »
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #8 : 13-03-2012 21:53 » |
|
Я в C# не работаю, но навскидку: 1. Не вижу цикла в onPaint 2. У тебя при установке свойств, вызываются команды перерисовки. А свойства ты меняешь в OnPaint - в результате происходит зацикливание.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #9 : 13-03-2012 22:47 » |
|
MasterMan342, проблема ещё осталась? Я не вижу цикла, о котором идёт речь.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
MasterMan342
|
|
« Ответ #10 : 14-03-2012 05:11 » |
|
MasterMan342, проблема ещё осталась? Я не вижу цикла, о котором идёт речь.
Закинь контрол на форму и в обработчик моего события (OnValueChanged) запихни цикл с какой нить функцией... вот тут у меня и возникает проблема) я не понимаю ее смысл, не считая зацикливания про которое zubr говорил. У меня в этом обработчике стояла обычная функция Convert.ToInt32("fdsfd", 16), ну типа конвертация в разные системы счисления... и даже при этом возникала проблема...
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #11 : 14-03-2012 06:58 » |
|
Те в твоём тестовом проекте этого нет?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
MasterMan342
|
|
« Ответ #12 : 14-03-2012 11:39 » |
|
Те в твоём тестовом проекте этого нет?
чего нет? события? пардон: OnChangedValue. Сам вызов события и его объявление находятся в области свойств... ну не знаю... странности продолжаются - я заметил что при запуске нескомпилированного проекта, т.е. при добавлении его кодового файла в другой проект, то контрол при щелчке получает крассный перекрест, и вырубается... при запуске из откомпилированной библиотеки - вылазит ошибка: Не удалось найти распознаваемые цифры. - сразу при выходе из обработчика... Я в C# не работаю, но навскидку: 1. Не вижу цикла в onPaint 2. У тебя при установке свойств, вызываются команды перерисовки. А свойства ты меняешь в OnPaint - в результате происходит зацикливание.
Я просмотрел свой onPaint, там нет изменения свойств, кроме разве-что изменения размера шрифта, но в свойстве font нет вызова на onPaint (Invalidate() - или это уже типа заложено, при изменении любого свойства автоматически все перерисовывать? нет-же?)
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #13 : 14-03-2012 12:04 » |
|
MasterMan342, я конечно тебя понимаю, ты уже давно с этим возишься, и тебе всё предельно понятно. Поэтому ты можешь позволить себе говорить обрывками мыслей. А теперь представь, что перед тобой человек, который вобще нифига не понимает ни в программировании, ни в разработке собственных контролов. Вот как бы ты ему объяснил задачу и проблему? Те у тебя есть контрол, который ты хочешь использовать в другом проекте, или в этом же проекте, но на другой форме? Это работает? Зачем нужен какой-то цикл? Ну и тд. Попробуй с самого начала всё просто объяснить. Пока я вижу тестовый проект, компилирую, выполняю, вроде всё работает. Кнопки переключаются. Никакого цикла (это его я имел ввиду, когда сказал "этого нет") нигде я не вижу. Жизнь прекрасна. Я просмотрел свой onPaint, там нет изменения свойств, кроме разве-что изменения размера шрифта, но в свойстве font нет вызова на onPaint (Invalidate() - или это уже типа заложено, при изменении любого свойства автоматически все перерисовывать? нет-же?) Вызов OnPaint и не нужен. Ты его не вызываешь. Это событие приходит от винды, когда она решает, что необходимо обновить окно (перерисовать). А вот сигналом к такой "провокации" служит вызов Invalidate. Те ты говоришь системе, что твоё окно "загрязнилось", в ответ на это получаешь OnPaint. А вызов Invalidate стоит у тебя практически в каждом свойстве.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
zubr
Гость
|
|
« Ответ #14 : 14-03-2012 12:28 » |
|
Я просмотрел свой onPaint, там нет изменения свойств, кроме разве-что изменения размера шрифта, но в свойстве font нет вызова на onPaint (Invalidate() - или это уже типа заложено, при изменении любого свойства автоматически все перерисовывать? нет-же?)
Ну вот, к примеру: public int _w { get { return w; } set { w = value; this.Invalidate(); this.Update(); }
}
//а это в OnPaint: w = Convert.ToInt32(fnt.Size) * onText.Length * 2;
|
|
|
Записан
|
|
|
|
MasterMan342
|
|
« Ответ #15 : 14-03-2012 12:29 » |
|
MasterMan342, я конечно тебя понимаю, ты уже давно с этим возишься, и тебе всё предельно понятно. Поэтому ты можешь позволить себе говорить обрывками мыслей. А теперь представь, что перед тобой человек, который вобще нифига не понимает ни в программировании, ни в разработке собственных контролов. Вот как бы ты ему объяснил задачу и проблему? Те у тебя есть контрол, который ты хочешь использовать в другом проекте, или в этом же проекте, но на другой форме? Это работает? Зачем нужен какой-то цикл? Ну и тд. Попробуй с самого начала всё просто объяснить. Пока я вижу тестовый проект, компилирую, выполняю, вроде всё работает. Кнопки переключаются. Никакого цикла (это его я имел ввиду, когда сказал "этого нет") нигде я не вижу. Жизнь прекрасна. Я просмотрел свой onPaint, там нет изменения свойств, кроме разве-что изменения размера шрифта, но в свойстве font нет вызова на onPaint (Invalidate() - или это уже типа заложено, при изменении любого свойства автоматически все перерисовывать? нет-же?) Вызов OnPaint и не нужен. Ты его не вызываешь. Это событие приходит от винды, когда она решает, что необходимо обновить окно (перерисовать). А вот сигналом к такой "провокации" служит вызов Invalidate. Те ты говоришь системе, что твоё окно "загрязнилось", в ответ на это получаешь OnPaint. А вызов Invalidate стоит у тебя практически в каждом свойстве. в общем, я пытался создать контрол-переключатель, на подобии checkbox. визуально он работает хорошо, есть свойство on отвечающее за состояние вкл/выкл (как выключатель обычный...). Я долго думал куда вызов события поместить, (пару дней назад только разобрался что же такое события...). ну вот и событие само происходит при изменении параметра on. лежит в обработчике MouseClick... все ок вроде)) обработчик моего события (OnChangedValue) запускает нормально все, но я в него ложу цикл перебирающий таблицу на форме и переводящий все значения из одной системы счисления в другую... да в принципе даже не важно, пробовал обычный метод convert в цикл ложить, - выдает ошибку (упомянутую выше)... уже и не знаю че не нравится этому событию. Добавлено через 2 минуты и 19 секунд:Я просмотрел свой onPaint, там нет изменения свойств, кроме разве-что изменения размера шрифта, но в свойстве font нет вызова на onPaint (Invalidate() - или это уже типа заложено, при изменении любого свойства автоматически все перерисовывать? нет-же?)
Ну вот, к примеру: public int _w { get { return w; } set { w = value; this.Invalidate(); this.Update(); }
}
//а это в OnPaint: w = Convert.ToInt32(fnt.Size) * onText.Length * 2;
ну вообщето w глобальная переменная, и изменение ее не должно нести вред, а вот если изменить в онпайнте значение свойства -W Добавлено через 6 дней, 17 часов, 53 минуты и 6 секунд:MasterMan342, потому что событие обрабатывается не асинхронно. Событие - это лишь замаскированный вызов процедуры. Т.е. представь, что ты в конец Paint вписал вызов процедуры с циклом.
Чтобы развязать эту связь, нужно в обработчике события запускать асинхронную задачу. Правда, потом придётся следить, чтобы параллельные асинхронные задачи не накладывались друг на друга во время исполнения или как-то иначе их синхронизировать.
Блин... у меня не получается, все равно выдает сообщение: не удалось найти распознаваемые цифры... как в обработчике события запустить асинхронную задачу??? у меня вызов события уже не в OnPaint лежит, с этим методом все ОК! вызов события должен протекать сразу после окончания OnPaint, и вызов стоит в обработчике MouseClick сразу после вызова OnPaint: void SwitchButton_MouseClick(object sender, MouseEventArgs e) { if (((e.X >= x) & (e.X <= x + this.Width / 2)) & ((e.Y >= y) & (e.Y <= y + this.Height))) { if (_on == true) { _on = false; //То-есть прорисовка все-же происходит при изменении свойства } ChangingValue(); //А после вызывается метод события. } ... } Добавлено через 1 час, 29 минут и 40 секунд:MasterMan342, потому что событие обрабатывается не асинхронно. Событие - это лишь замаскированный вызов процедуры. Т.е. представь, что ты в конец Paint вписал вызов процедуры с циклом.
Чтобы развязать эту связь, нужно в обработчике события запускать асинхронную задачу. Правда, потом придётся следить, чтобы параллельные асинхронные задачи не накладывались друг на друга во время исполнения или как-то иначе их синхронизировать.
Блин... у меня не получается, все равно выдает сообщение: не удалось найти распознаваемые цифры... как в обработчике события запустить асинхронную задачу??? у меня вызов события уже не в OnPaint лежит, с этим методом все ОК! вызов события должен протекать сразу после окончания OnPaint, и вызов стоит в обработчике MouseClick сразу после вызова OnPaint: void SwitchButton_MouseClick(object sender, MouseEventArgs e) { if (((e.X >= x) & (e.X <= x + this.Width / 2)) & ((e.Y >= y) & (e.Y <= y + this.Height))) { if (_on == true) { _on = false; //То-есть прорисовка все-же происходит при изменении свойства } ChangingValue(); //А после вызывается метод события. } ... } Я даже убрал событие перерисовки, и в итоге получается что само событие вызывает исключение, почему?
|
|
« Последнее редактирование: 21-03-2012 07:54 от MasterMan342 »
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #16 : 21-03-2012 08:12 » |
|
MasterMan342, телепатов тут нет. Откуда кто знает что у тебя в обработчике события ChangingValue. Как я понимаю отттуда у тебя выскакивает исключение. Возьми и пройдись отладчиком по коду твоего события - увидишь что вызывает исключение.
|
|
|
Записан
|
|
|
|
MasterMan342
|
|
« Ответ #17 : 21-03-2012 09:03 » |
|
MasterMan342, телепатов тут нет. Откуда кто знает что у тебя в обработчике события ChangingValue. Как я понимаю отттуда у тебя выскакивает исключение. Возьми и пройдись отладчиком по коду твоего события - увидишь что вызывает исключение.
public event EventHandler OnChangingValue; protected void ChangingValue() { if (OnChangingValue != null) { OnChangingValue(this, new EventArgs()); } }
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #18 : 21-03-2012 10:17 » |
|
А что в OnChangingValue?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #19 : 21-03-2012 10:38 » |
|
MasterMan342, выложи проект с ОШИБКОЙ. Вот с этим вот: я в него ложу цикл перебирающий таблицу на форме и переводящий все значения из одной системы счисления в другую... да в принципе даже не важно, пробовал обычный метод convert в цикл ложить, - выдает ошибку (упомянутую выше)
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #20 : 21-03-2012 10:46 » |
|
Из личного сообщения мне: Привет) я хотел задать вопрос по поводу событий (еще по поводу той кнопки): вроде как нашел корень проблемы - перенес событие в отдельный проект, пустой... событие вызывается при простом нажатии на кнопку:
public partial class Form1 : Form { public Form1() { InitializeComponent(); this.OnChangingValue += new EventHandler(Ev); }
public event EventHandler OnChangingValue;
protected void ChangingValue() { if (OnChangingValue != null) //Предположительно пропускной пункт, между += и -= { OnChangingValue(this, new EventArgs()); } }
private void Ev(object sender, EventArgs e) { string a = ""; for (int i = 0; i < 30; i++) { a += Convert.ToInt32(i.ToString(), 2).ToString(); } //Это как-раз тот цикл в обработчике про который я говорил... }
private void button1_Click(object sender, EventArgs e) { ChangingValue(); } }
в итоге, после нажатии на кнопку выскакивает исключение еще на вызове в методе Main() - Application.Run(new Form1());. Не удалось найти распознаваемые числа, и цикл проходит из 30 всего 2 оборота... Не ругай сильно , я изучаю си еще только пол года , и еще многого не знаю... По тексту очевидно, что это ошибка конвертирования чисел, а никак не проблемы с отрисовкой или что-то ещё. Convert.ToInt32(i.ToString(), 2).ToString() Что это за танцы с бубном?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
MasterMan342
|
|
« Ответ #21 : 21-03-2012 14:47 » |
|
Ага) спасибо разобрался, тема закрыта!
|
|
« Последнее редактирование: 21-03-2012 16:10 от Джон »
|
Записан
|
|
|
|
|