我想在Windows Forms应用程序中模拟“Web2.0”Lightbox风格的UI技术。也就是说,通过“调暗”窗口客户区中的所有其他内容来将注意力吸引到一些前景控件上。
显而易见的解决方案是创建一个控件,它只是一个部分透明的矩形,可以停靠到窗口的工作区,并放在Z顺序的前面。它需要表现得像一个肮脏的玻璃之痛,通过它仍然可以看到其他控件(并因此继续绘制自己)。这个是可能的吗?
我进行了一次很好的搜寻,并尝试了一些技巧,但到目前为止还没有成功。如果这是不可能的,还有什么方法可以做到呢?
参见:http://www.useit.com/alertbox/application-design.html (在Lightbox部分下面提供了一个屏幕截图来说明我的意思)。
发布于 2008-09-16 14:52:19
你能在.NET/C#中做到这一点吗?
是的,你当然可以,但这需要一点努力。我推荐以下方法。创建一个没有边框或标题栏区域的顶层窗体,然后通过将TransparencyKey和BackColor设置为相同的值,确保它不绘制客户区背景。所以你现在有了一个什么都没画的窗口。
public class DarkenArea : Form
{
public DarkenArea()
{
FormBorderStyle = FormBorderStyle.None;
SizeGripStyle = SizeGripStyle.Hide;
StartPosition = FormStartPosition.Manual;
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
BackColor = Color.Magenta;
TransparencyKey = Color.Magenta;
Opacity = 0.5f;
}
}
创建此DarkenArea窗口并将其放置在窗体的工作区上。然后,您需要能够在不获取焦点的情况下显示窗口,因此您将需要以以下方式进行平台调用,以在不激活窗口的情况下进行显示……
public void ShowWithoutActivate()
{
// Show the window without activating it (i.e. do not take focus)
PlatformInvoke.ShowWindow(this.Handle, (short)SW_SHOWNOACTIVATE);
}
你需要让它实际绘制一些东西,但排除在你想要保持高亮显示的控件区域中的绘制。因此,覆盖OnPaint处理程序,绘制黑色/蓝色或任何你想要的,但不包括你想要保持明亮的区域…
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Do your painting here be exclude the area you want to be brighter
}
最后,如果用户尝试一些疯狂的操作,比如单击变暗的区域,您需要覆盖WndProc以防止鼠标与窗口交互。就像这样..。
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WM_NCHITTEST)
m.Result = (IntPtr)HTTRANSPARENT;
else
base.WndProc(ref m);
}
这应该足以获得所需的效果。当您准备好反转效果时,您可以处理DarkenArea实例并继续。
发布于 2008-10-04 06:12:07
这是一个非常酷的想法--我可能会用到它,所以谢谢。不管怎样,我的解决方案很简单...在当前窗体上打开一个50%不透明的新窗体,然后自定义地为该窗体绘制一个背景图像,其中的矩形与您要突出显示的控件的边界相匹配,并以透明键的颜色填充。
在我的粗略示例中,我将这个表单称为“LBform”,其实质是:
public Rectangle ControlBounds { get; set; }
private void LBform_Load(object sender, EventArgs e)
{
Bitmap background = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(background);
g.FillRectangle(Brushes.Fuchsia, this.ControlBounds);
g.Flush();
this.BackgroundImage = background;
this.Invalidate();
}
Color.Fuchia是这个半透明窗体的TransparencyKey,因此您将能够看到绘制的矩形,并与其在主窗体上的边界内的任何内容交互。
在我提出的实验项目中,我使用了一个动态添加到窗体中的UserControl,但您也可以很容易地使用窗体上已有的控件。在主窗体(您正在隐藏的窗体)中,我将相关代码放入一个按钮中,单击:
private void button1_Click(object sender, EventArgs e)
{
// setup user control:
UserControl1 uc1 = new UserControl1();
uc1.Left = (this.Width - uc1.Width) / 2;
uc1.Top = (this.Height - uc1.Height) / 2;
this.Controls.Add(uc1);
uc1.BringToFront();
// load the lightbox form:
LBform lbform = new LBform();
lbform.SetBounds(this.Left + 8, this.Top + 30, this.ClientRectangle.Width, this.ClientRectangle.Height);
lbform.ControlBounds = uc1.Bounds;
lbform.Owner = this;
lbform.Show();
}
非常基本的东西,如果你喜欢,你可以用你自己的方式来做,但它只是添加用户控件,然后在主窗体上设置lightbox窗体,并设置bounds属性以在正确的位置呈现完整的透明度。在我的快速示例中没有处理表单拖拽和关闭lightbox表单和UserControl之类的事情。哦,别忘了处理Graphics实例--我也遗漏了这个(很晚了,我真的很累)。
发布于 2008-09-16 14:40:36
窗体本身具有完美的Opacity
属性,但我不认为大多数单独的控件都具有该属性。你得自己画。
https://stackoverflow.com/questions/72994
复制相似问题