OP: 如果有其他语言/环境我可以处理
这个问题,我当然准备试试了。
所以除了 Windows Forms 解决方案之外,我还会分享一个 WPF 解决方案(这是一个更好的框架来满足这个要求):
- Windows 窗体 - 拥有的窗体
- Windows 窗体 - 分层窗口
- WPF - 透明表单和控制不透明度
Windows 窗体 - 拥有的窗体
作为一个选项,您可以使用自有表单。
每个面板都可以是主窗体拥有的顶级无边框窗体。主窗体具有与其背景颜色相同的透明度键,而那些拥有的窗体具有不透明度。这样,您应该处理主表单的移动并同时移动拥有的表单:
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 窗体 - 分层窗口
作为一个选项,您可以使用Layered Windows。
这样您可以在运行时创建半透明图像并将其设置为表单的背景图像。但是您的表单不会收到任何绘制事件,因此在此类表单上托管控件是没有意义的(但是它们正在工作并且您可以以某种方式强制这些控件重新绘制)。
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 - 具有不透明度的透明表单和控件
满足此类 UI 要求的更好框架是 WPF。
为此,您可以将窗口的Background 设置为Transparent,将WindowStyle 设置为None,并将AllowTransparency 设置为True。同样对于每个控件,您可以简单地设置Opacity 值:
<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>