问题
I have already read many topics about opacity/transparency on Windows Forms in C#, but it's not the effect I would like to get. I would like Form
to be 100% transparent, but transparency of the Panel
was adjustable, and the transparency effect was transferred to the elements behind Form (Windows desktop, web browser e.t.c.). The attached photo shows the effect that I would like to get (I made them in a graphic program). I will be grateful for your help.
回答1:
OP: If there is any other language / environment in which I can deal with this problem, of course I am ready to try it.
So in addition to Windows Forms solutions, I'll share a WPF solution as well (which is a better framework to satisfy this requirement):
- Windows Forms - Owned Forms
- Windows Forms - Layered Windows
- WPF - Transparent Form and Control Opacity
Windows Forms - Owned Forms
As an option you can use Owned Forms.
Each of the panels can be a top-level border-less Form owned by the main form. The main has a transparency key equal to its back color and those owned forms has opacity. This way you should handle moving of the main form and move the owned forms as well:
public partial class MyOwnerForm : Form
{
public MyOwnerForm()
{
InitializeComponent();
this.BackColor = Color.Magenta;
this.TransparencyKey = Color.Magenta;
this.StartPosition = FormStartPosition.Manual;
this.DesktopLocation = new Point(100, 100);
this.ClientSize = new Size(330, 330);
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
CreateForm(1, new Point(10, 10), new Size(150, 150)).Show();
CreateForm(0.75, new Point(170, 10), new Size(150, 150)).Show();
CreateForm(0.50, new Point(10, 170), new Size(150, 150)).Show();
CreateForm(0.25, new Point(170, 170), new Size(150, 150)).Show();
}
protected override void OnMove(EventArgs e)
{
base.OnMove(e);
if(OwnedForms.Length>0)
{
var p = PointToScreen(new Point(10, 10));
var dx = p.X - OwnedForms[0].Location.X;
var dy = p.Y - OwnedForms[0].Location.Y;
foreach (var f in OwnedForms)
f.Location= new Point(f.Location.X+dx, f.Location.Y+dy);
}
}
Form CreateForm(double opacity, Point location, Size size)
{
var f = new Form();
f.FormBorderStyle = FormBorderStyle.None;
f.BackColor = Color.Lime;
f.Opacity = opacity;
f.StartPosition = FormStartPosition.Manual;
f.DesktopLocation = PointToScreen(location);
f.ClientSize = size;
f.Owner = this;
f.ShowInTaskbar = false;
return f;
}
}
Windows Forms - Layered Windows
As an option you can use Layered Windows.
This way you can create the semi transparent image at run-time and set it as background image of your form. But your form will not receive any paint event and so hosting control on such form is pointless (however they are working and you somehow can force those control repaint).
public partial class MyLayeredForm : PerPixelAlphaForm
{
public MyLayeredForm()
{
InitializeComponent();
var bm = new Bitmap(230, 230);
using (var g = Graphics.FromImage(bm))
{
using (var b = new SolidBrush(Color.FromArgb(255, Color.Lime)))
g.FillRectangle(b, 10, 10, 100, 100);
using (var b = new SolidBrush(Color.FromArgb(255 * 75 / 100, Color.Lime)))
g.FillRectangle(b, 120, 10, 100, 100);
using (var b = new SolidBrush(Color.FromArgb(255 * 50 / 100, Color.Lime)))
g.FillRectangle(b, 10, 120, 100, 100);
using (var b = new SolidBrush(Color.FromArgb(255 * 25 / 100, Color.Lime)))
g.FillRectangle(b, 120, 120, 100, 100);
}
this.SelectBitmap(bm);
}
}
WPF - Transparent Form and Controls having Opacity
A better framework to satisfy such UI requirement is WPF.
To do so, you can set Background
of window to Transparent
and WindowStyle
to None
and set AllowTransparency
to True
. Also for each control you can simply set Opacity
value:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="261.154" Width="232.923"
Background="Transparent" AllowsTransparency="True"
WindowStyle="None" WindowStartupLocation="CenterScreen">
<Grid Margin="0,0,0,0">
<Grid HorizontalAlignment="Left" Height="100"
Margin="10,10,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="1"/>
<Grid HorizontalAlignment="Left" Height="100"
Margin="120,10,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="0.75"
Grid.ColumnSpan="2"/>
<Grid HorizontalAlignment="Left" Height="100"
Margin="10,120,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="0.50"/>
<Grid HorizontalAlignment="Left" Height="100"
Margin="120,120,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="0.25"
Grid.ColumnSpan="2"/>
</Grid>
</Window>
回答2:
panel doesn't have opacity property. For making a panel transparent you should use a customised panel like this...
Imports System.ComponentModel
Partial Public Class C_PANEL
Inherits Panel
Private Const WS_EX_TRANSPARENT As Integer = &H20
Public Sub NewP()
SetStyle(ControlStyles.Opaque, True)
End Sub
Public Sub NewP(con As IContainer)
con.Add(Me)
End Sub
Private iopacity As Integer = 50
<DefaultValue(50)>
Public Property Opacity() As Integer
Get
Return Me.iopacity
End Get
Set(value As Integer)
If Value < 0 OrElse Value > 100 Then
Throw New ArgumentException("value must be between 0 and 100")
End If
Me.iopacity = Value
End Set
End Property
Protected Overrides ReadOnly Property CreateParams() _
As CreateParams
Get
Dim cpar As CreateParams = MyBase.CreateParams
cpar.ExStyle = cpar.ExStyle Or WS_EX_TRANSPARENT
Return cpar
End Get
End Property
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Using brush = New SolidBrush(Color.FromArgb(Me.Opacity _
* 255 / 100, Me.BackColor))
e.Graphics.FillRectangle(brush, Me.ClientRectangle)
End Using
MyBase.OnPaint(e)
End Sub
End Class
after creating this control you can add this panel to form and can set opacity according to you.
and the form has its own opacity property that can be set easily.
来源:https://stackoverflow.com/questions/51012168/c-sharp-windows-forms-semi-opacity