Как сделать PictureBox по-настоящему прозрачным

У меня есть PictureBox, который можно перемещать по вертикали. Изображение, отображаемое в PictureBox, представляет собой прозрачный GIF-файл, поэтому при просмотре в средстве просмотра изображений у него нет фона.

Проблема в том, что когда я перемещаю PictureBox в приложении, фон PictureBox перемещается слишком странно - почти как если бы PictureBox сам имел фон.

До:

введите описание изображения здесь

После (во время движения):

введите описание изображения здесь

Какой-то код:

path = "C:\\note.gif";
note.Image = Image.FromFile(path);
note.Visible = true;
note.BackColor = Color.Transparent;
panel.Controls.Add(note);

Я также пробовал сделать двойную буферизацию Picturebox, но это тоже не сработало.


person Dot NET    schedule 31.12.2011    source источник
comment
Что произойдет, если вы замените свой GIF на PNG с установленной прозрачностью?   -  person ChrisF    schedule 31.12.2011
comment
Пробовал PNG перед GIF, к сожалению, тот же сценарий.   -  person Dot NET    schedule 31.12.2011
comment
Помогает ли звонок note.Invalidate(); после перемещения? Или panel.Invalidate();?   -  person LarsTech    schedule 31.12.2011
comment
По сути, ваш подход ошибочен, потому что использование графического блока для каждой музыкальной ноты - не лучший подход. В идеале вы должны рисовать все на своей панели и обрабатывать события нажатия мыши для выбора заметок на основе координат. Все рисование происходит в панели. Когда вы перемещаете заметку, вы снова ее перерисовываете.   -  person LarsTech    schedule 31.12.2011
comment
К сожалению, PictureBox - это строгое требование. Поверьте, если бы это было не так, я бы использовал что-то другое - это вызвало столько проблем на пути.   -  person Dot NET    schedule 31.12.2011


Ответы (2)


Хотя WinForms плохо подходит для прозрачности пользовательских элементов управления, это возможно. См. эту статью здесь. В нем автор предлагает наследовать от Panel, а не от UserControl, и переопределить метод OnPaintBackground, чтобы ничего не делать. это остановит отрисовку фона

protected override void OnPaintBackground(PaintEventArgs pevent)
{
    //do nothing
}

protected override void OnMove(EventArgs e)
{
    RecreateHandle();
}

// Override the CreateParams property:
protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle = 0x00000020; //WS_EX_TRANSPARENT
        return cp;
    }
}

Наконец, переопределив функцию OnPaint, вы можете нарисовать свой графический блок.

protected override void OnPaint(PaintEventArgs e)
{
    Graphics g = e.Graphics;

    //Do your drawing here
}

Используя это, вы можете создать настраиваемое графическое окно с прозрачностью, хотя обратите внимание, что вы получите мерцание и размытие, если вы будете перемещать его по экрану в реальном времени.

Используя этот и аналогичные методы, нам удалось получить приложение WinForms, Premex XPort для рендеринга с таким же брендингом, что и их веб-сайт. Это включало в себя несколько прозрачных элементов управления, хаки для рисования и всевозможные способы правильного отображения.

В заключение, причина, по которой Winforms делает это плохо, заключается в технологиях на основе Win32, один элемент управления владеет одним пикселем на экране. Невозможно создать действительно составные пиксели с прозрачностью, как можно было бы ожидать в HTML или WPF. Более поздние технологии Windows (WPF) делают это особенно хорошо, поэтому, если вы действительно хотите интенсивно использовать прозрачность в своем приложении, я бы предложил перейти на эту платформу, по крайней мере, частично (WPF может быть размещен в WinForms и наоборот).

С наилучшими пожеланиями,

person Dr. Andrew Burnett-Thompson    schedule 31.12.2011
comment
Большое спасибо за помощь - завтра попробую :) - person Dot NET; 01.01.2012

Элементы управления Win32 не совсем прозрачны.

Ваш выбор:

  • Перейти на WPF
  • Используйте PictureBox.Region, чтобы вырезать ненужные («прозрачные») области элемента управления.
  • Посмотрите, есть ли сторонние элементы управления, которые будут делать то, что вы хотите
person John Arlen    schedule 31.12.2011
comment
Итак, по сути, вы говорите, что нет способа решить эту проблему с помощью WinForms? Помимо PictureBox.Region, который вообще не жизнеспособен, поскольку у меня есть множество различных типов PictureBox - person Dot NET; 31.12.2011
comment
@Sean no way немного растягивает его, но это просто не стоит усилий, и результат всегда будет выглядеть фальшивым - Windows Forms, в отличие от WPF, не создавался с учетом этих соображений. Я не знаю, почему использование WinForms PictureBox является обязательным, но если бы это был реальный проект, я бы посоветовал вам выбрать правильные инструменты для работы . - person Adam; 31.12.2011
comment
Это проект для университета - поэтому это требование :) Если бы это был реальный проект, он был бы более практичным. - person Dot NET; 01.01.2012
comment
Я называю этот ответ чушью. Я делал ИСТИННЫЕ прозрачные элементы управления, используя Windows API в VB6, хотя изначально он никогда не поддерживался. Также можно сделать в Delphi (элементы управления win32) и так далее. Вы также можете сделать это (отличный пример) в текущей версии для всей формы codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C). Возможно, кто-то сможет настроить это для работы с элементами управления, предоставив элементам управления ручку, поскольку M $ так любезно удалил ручки. - person Kraang Prime; 21.07.2014
comment
@SanuelJackson Не уверен, что ваш ответ имеет смысл. Вы называете козлом без доказательств обратного. Взлом, сделанный 10 лет назад, и неподтвержденное заявление о том, что он все равно не поддерживается изначально. Если бы существовала истинная (т.е. поддерживаемая) прозрачность, ее было бы легко продемонстрировать. - person PandaWood; 15.12.2014