сделать - прозрачность picturebox c#




Как создать прозрачный элемент управления, который работает, когда поверх других элементов управления? (5)

Некоторые предложения (извинения за код VB).

Старайтесь не рисовать фон:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If m.Msg = &H14 Then
        Return
    End If
    MyBase.WndProc(m)
End Sub

Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
    Return
End Sub

Не вызывайте базовый метод рисования элементов управления:

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    'MyBase.OnPaint(e) - comment out - do not call
End Sub

У меня есть элемент управления (полученный из System.Windows.Forms.Control), который должен быть прозрачным в некоторых областях. Я реализовал это с помощью SetStyle ():

public TransparentControl()
{
    SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    this.BackColor = Color.Transparent.
}

Теперь это работает, если между формой и прозрачным элементом управления нет элементов управления. Однако, если под прозрачным элементом управления есть другой элемент управления (который здесь используется), он не работает. Промежуточный контроль не является ничьей, но форма ниже показывает сквозную. Я могу получить необходимый эффект, переопределив CreateParams и установив флешку WS_EX_TRANSPARENT следующим образом:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT
        return cp;
    }
}

Проблема здесь в том, что это действительно замедляет рисование элемента управления. Элемент управления уже имеет двойную буферизацию, так что тут нечего делать. Хит производительности настолько плох, что это недопустимо. Кто-нибудь еще сталкивался с этой проблемой? Все ресурсы, которые я могу найти, предлагают использовать метод № 1, но, опять же, это не работает в моем случае.

РЕДАКТИРОВАТЬ: я должен отметить, что у меня есть обходной путь. Дочерние (прозрачные) элементы управления могут просто рисовать себя на объекте Graphics родительского объекта, но это действительно неуклюже, и мне не нравится решение вообще (хотя это может быть все, что у меня есть).

РЕДАКТИРОВАТЬ 2: Итак, следуя совету, который я получил о том, как прозрачность работает в .NET, я реализовал интерфейс IContainer в своем пользовательском элементе управления, который содержит прозрачные элементы управления. Я создал класс, который реализует ISite, я добавляю свои дочерние элементы управления в коллекцию Components UserControl, свойство Container корректно выравнивается в отладчике, но я все еще не получаю эффект прозрачности. У кого-нибудь есть какие-либо идеи?


Прозрачные элементы управления в DotNet реализуются путем рисования контейнера прозрачного элемента управления в окне прозрачного элемента управления, а затем с помощью элемента управления прозрачного элемента. Этот процесс не учитывает возможность перекрытия элементов управления. Таким образом, вам нужно будет использовать какой-то обходной путь, чтобы заставить его работать.

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


Это делает трюк, по крайней мере, это для меня:

protected override void OnPaintBackground(PaintEventArgs e)
{
    //base.OnPaintBackground(e);
    this.CreateGraphics().DrawRectangle(new Pen(Color.Transparent, 1), new Rectangle(0, 0, this.Size.Width, this.Size.Height));
}

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

Он работает, рисуя элемент управления, который находится позади / пересекается с текущим элементом управления в растровом изображении, а затем выводит это растровое изображение в текущий элемент управления.

protected override void OnPaint(PaintEventArgs e)
{
    if (Parent != null)
    {
        Bitmap behind = new Bitmap(Parent.Width, Parent.Height);
        foreach (Control c in Parent.Controls)
            if (c.Bounds.IntersectsWith(this.Bounds) & c != this)
                c.DrawToBitmap(behind, c.Bounds);
        e.Graphics.DrawImage(behind, -Left, -Top);
        behind.Dispose();
    }
}

Я решил просто нарисовать родителя под своими дочерними элементами управления вручную. Вот хорошая статья.





transparent-control