Sal*_*leh 7 c# opacity winforms
我有一个自己有一些控件的表单(btnCreateReport,pnlDarkLayer).我有一个适合形成的面板(Dock = Fill),它位于所有控件的背面.当用户点击btnCreateReport按钮时,我调用pnlDarkLayer BringToFront方法,经过一些计算,我调用了按钮的SendToBack()方法.我想在窗体控件上绘制一个暗层,并禁用窗体上的所有控件.可能吗?谢谢.
也许这段代码可以帮助你理解我的目的:
private void btnCreateReport_Click(object sender, EventArgs e)
{
pnlDarkLayer.BackColor = Color.FromArgb(100, Color.Gray);
pnlDarkLayer.BringToFront();
btnCreateReport.Enabled = false;
Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport));
ProcessReport.Start();
while (ProcessReport.IsAlive)
{
Application.DoEvents();
}
pnlDarkLayer.SendToBack();
btnCreateReport.Enabled = true;
}
Run Code Online (Sandbox Code Playgroud)
此代码隐藏所有控件但我不想隐藏窗体上的控件.我想在它们上绘制一个暗层.用户必须能看到控件.我需要像控件的表单的不透明属性.
我测试了这个:
pnlDarkLayer.CreateGraphics().CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceOver;
更新:我测试了这个:(使用表单而不是面板)
private void btnCreateReport_Click(object sender, EventArgs e)
{
btnCreateReport.Enabled = false;
frmProgress ProgressForm = new frmProgress();
ProgressForm.TopLevel = false;
ProgressForm.Parent = this;
ProgressForm.BringToFront();
this.Controls.Add(ProgressForm);
ProgressForm.Show();
Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport));
ProcessReport.Start();
while (ProcessReport.IsAlive)
{
Application.DoEvents();
}
ProgressForm.Close();
btnCreateReport.Enabled = true;
}
Run Code Online (Sandbox Code Playgroud)
但我无法在我的表单中看到ProgressForm.
从 http://support.microsoft.com/kb/943454
WinForms中的透明控件相对于其父级是透明的,而不是其他控件.WinForms中的透明度更像伪装而非真正的透明度.透明控件实际上不会让您通过表单看到它背后的控件.它要求其父母在"透明"控件上绘制自己的背景.这就是透明控件显示其背后的形式,但掩盖任何其他控件的原因.
要实现相对于其他控件的透明度,需要做同样的事情,但需要更大规模:不要只是要求父级绘制前景控件的背景,控件需要让它后面的所有控件都在其背景上绘制.这仅适用于控件,这些控件提供了一些请求绘制它们的方法,并且在后台控件的图像更改时不会自动更新.
该页面还提供了一个代码示例(在vb中,遗憾地),以显示如何完成此操作.
如果我理解正确,您希望在操作运行时"变暗"表单的内容.
正如有人在此之前说的那样,做正确的做法非常棘手.但有一种方法可以轻松完成,只需一次预订(见下文).
看看这个源代码:
public partial class Form1 : Form
{
private Bitmap _background;
private bool _isShrouded;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (true == _isShrouded && null!=_background)
e.Graphics.DrawImage(_background, 0, 0);
}
public void Shroud()
{
if (false == _isShrouded)
{
CreateScreenshot();
HideControls();
_isShrouded = true;
this.Invalidate();
}
}
public void Unshroud()
{
if (true == _isShrouded)
{
ShowControls();
_isShrouded = false;
this.Invalidate();
}
}
private void HideControls()
{
foreach (Control control in this.Controls)
control.Visible = false;
}
private void ShowControls()
{
foreach (Control control in this.Controls)
control.Visible = true;
}
private void CreateScreenshot()
{
Rectangle area = this.RectangleToScreen(this.ClientRectangle);
Bitmap screenGrab = new Bitmap(area.Width, area.Height);
Brush dark = new SolidBrush(Color.FromArgb(128, Color.Black));
Graphics g = Graphics.FromImage(screenGrab);
g.CopyFromScreen(area.Location, Point.Empty, area.Size);
g.FillRectangle(dark, 0, 0, area.Width, area.Height);
g.Dispose();
_background = screenGrab;
}
}
Run Code Online (Sandbox Code Playgroud)
Form1类有两个主要方法,Shroud()和Unshroud().
Shroud()方法获取表单的快照,并将其复制到位图中,然后将其"变暗".然后隐藏控件,并在表单上绘制位图.
UnShroud()方法恢复控件,并告诉表单不再绘制位图.
它需要两个私有变量:一个用于存储位图,另一个用于维护当前状态.
它还会覆盖OnPaint(),因为它需要在"覆盖"时绘制背景图像.
注意:通过截取表单的屏幕截图来实现覆盖.这意味着形式必须是覆盖点上最顶层的形式.如果表单被其他表单遮盖,则它们将包含在屏幕截图中.我希望这对你来说不是问题.
注意:如前所述,实现Windows透明性的唯一方法是所有相关控件的全面合作,这是一项艰巨的任务.其他任何东西(包括这个解决方案)实际上都是骗局.
| 归档时间: |
|
| 查看次数: |
9674 次 |
| 最近记录: |