Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Рисование на контроле Panel...


Автор: CyraxZ 31.5.2007, 21:52
Аналогично рисованию на форме (получаем объект Graphics методом Form.CreateGraphics() и рисуем на нём) получаю объект Graphics для контрола Panel (Panel.CreateGraphics) и рисую на нём... в результате ничего не отображается...
Пробовал и очистку панели методом Clear(произвольный цвет) - никакой реакции...

Автор: emmanuil 1.6.2007, 05:49
Попробуй код, все нормально рисует. Возьми новую панельку и примени к ней этот код, должно работать
Код

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            points = new ArrayList();
            pen = new Pen(Color.Blue, 5);
        }

        ArrayList points;
        Pen pen;

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            points.Clear();
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point pt = new Point(e.X, e.Y);
                points.Add(pt);
                if (points.Count <= 1) return;
                Point[] pts = new Point[points.Count];
                points.CopyTo(pts, 0);
                Graphics graph = panel1.CreateGraphics();
                graph.DrawCurve(pen, pts);
            }
        }

Автор: Mag 2.6.2007, 19:12
Тоже такая же проблемка была. По примеру выше создал новую панельку, Работает!

emmanuil, Спасибо.

Автор: CyraxZ 2.6.2007, 21:25
Чёрт, просмотрел одну деталь...
Рисовал-то я на панельке в событии OnLoad формы, когда ещё панель не была создана...

Тут у меня попутно ещё такой вопрос возник:
Почему у панели Panel нет событий OnLoad и OnClose, подобно форме ?
Мне нужны события, генерируемые после создания панели (пока остановился на событии Layout, хотя это не совсем то) и перед её уничтожением или скрытием...

Автор: emmanuil 5.6.2007, 05:52
У панели есть события:
Paint - когда рисует панель,
Disposed - когда вызывается метод Dispose,
VisibleChanged - когда изменяется свойство Visible.
VisibleChanged - происходит два раза при создании формы. В первый раз, еогда панель добавляется на форму(visible = false), а второй уже когда visible = true. А потом Происходит Paint
Я думаю тебе подойдет последнее в обоих случаях. Проверяй Visible и выполняй код.

Автор: CyraxZ 27.6.2007, 18:06
По поводу Dispose: почему наследуемые события не отображаются в Property Window ?

А что касается VisibleChanged, то это событие (у панели) при формировании формы у меня вызывается 2 раза с Visible = false (почему - непонятно) и 3-й раз - с Visible = true.
И не будет ли проблем при использовании этого события, скажем, при перекрытии формы другой формой ?  Ведь в этом случае Visible = true и начинают выполняться действия, которые должны выполняться при закрытии формы/панели...

Автор: CyraxZ 27.6.2007, 18:33
... (не туда напостил)

Автор: CyraxZ 29.6.2007, 07:15
dsi...

Автор: CyraxZ 29.6.2007, 19:36
Вопрос уже ребром встал. Глюки страшные из-за того, что отписка от событий, при обработке которых перерисовывается панель, происходит после того, как панель деструктурируется. В итоге имеем попытки рисования на панели тогда, когда её уже нет...

Нужно найти или сформировать событие, генерируемое перед уничтожением панели (аналог события закрытия формы)...

Автор: tol05 30.6.2007, 10:41
Код

public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      panel1.Disposed += Alert;  //Вот на него привязывайся
    }

    private void Alert(object sender, EventArgs e)
    {
      Text = "The panel has been disposed";
    }

    private void button1_Click(object sender, EventArgs e)
    {
      panel1.Dispose();
    }
  }

Автор: emmanuil 2.7.2007, 05:05
CyraxZ, ты самостоятельно уничтожаешь панель, то как я и говорил, а tol05 показал, используй событие dispose. А если ты не контролируешь этот процесс, то тогда VisibleChanged, в обработчике проверяй существование панели и visible. А если все же не получится выложи этот код, разберемся

Добавлено через 14 минут и 54 секунды
Еще можно деструктор переписать

Автор: CyraxZ 4.7.2007, 18:01
Обсуждение откладывается на месяц (вышел в отпуск... ура...)

Автор: mr.DUDA 11.7.2007, 21:09
Чтобы не делать ничего после уничтожения панели или т.п. контрола, достаточно проверить свойство IsDisposed.

Автор: CyraxZ 1.8.2007, 23:08
Цитата

Чтобы не делать ничего после уничтожения панели или т.п. контрола, достаточно проверить свойство IsDisposed.


Чтобы ничего не проверять, лучше делать все дела в обработчике события, которое генерируется до фактического закрытия и освобождения формы, а не после, как Disposed. Тогда не придётся ничего проверять...
В случае с Disposed бывают ситуации, когда событие генерируется прямо перед уничтожением формы/контрола. И в обработчике этого события приходится работать с уничтоженным контролом. Проверка на IsDisposed обязательна...
Собственно, нужно найти событие, которое генерируется до уничтожения формы/контрола.


tol05
По поводу события Disposed.
В хелпе указано:
Код

public delegate void EventHandler(Object sender, EventArgs e);
public event EventHandler NoDataEventHandler;

Тогда почему следующая строка не работает:
Код

this.MainSchemePanel.Disposed += System.EventHandler(MainSchemePanel_Dispose);

а эта - работает:
Код

this.MainSchemePanel.Disposed += MainSchemePanel_Dispose;

Ведь для событий справа от инремента всегда должно стоять приведение к типу соответствующего делегата...

Автор: tol05 2.8.2007, 19:34
Цитата(CyraxZ @  1.8.2007,  23:08 Найти цитируемый пост)
Тогда почему следующая строка не работает:

код C#    
1:    
this.MainSchemePanel.Disposed += System.EventHandler(MainSchemePanel_Dispose);    

а эта - работает:

код C#    
1:    
this.MainSchemePanel.Disposed += MainSchemePanel_Dispose;

да потому, что нужно писать
Код

this.MainSchemePanel.Disposed += new System.EventHandler(MainSchemePanel_Dispose);

Автор: CyraxZ 3.8.2007, 12:09
Да, действительно. Пропустил "new". Но почему конструкция работает без приведения к типу делегата ?
В случаях с обработчиками событий Paint, Load и т.д. компилятор требует этого приведения...

Автор: tol05 3.8.2007, 12:48
Цитата(CyraxZ @  3.8.2007,  12:09 Найти цитируемый пост)
Но почему конструкция работает без приведения к типу делегата ?

Это "групповое преобразование методов", фича компилятора 2.0, появившаяся вместе с анонимными методами. Встретив конструкцию
Код

MyObj.MyEvent += MyHandler;

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

Если событийный делегат у нас например EventHandler, то можно даже так писать:
Код

EventHandler handler = (EventHandler)MyHandler;

Цитата(CyraxZ @  3.8.2007,  12:09 Найти цитируемый пост)
В случаях с обработчиками событий Paint, Load и т.д. компилятор требует этого приведения...

Не знаю. На втором фрейморке я кроме как 
MyForm.Load += MyHandler;
не пишу уже давненько...

Автор: CyraxZ 14.8.2007, 18:59
Как добраться до конструктора панели, расположенной на форме ?
Мне нужно событие, которое генерируется непосредственно после создания панели на форме. Конструктор панели  - идеальный вариант (в конце конструктора можно выполнить свои действия или вызвать свою процедурку).
Пока использую событие HandleCreated панели, но это, насколько я понимаю, не совсем то, что нужно...

Автор: CyraxZ 22.8.2007, 11:39
Так 
Код

this.MainSchemePanel.Disposed += System.EventHandler(MainSchemePanel_Dispose);
  работает и без new...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)