Как да направите 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