六、双层窗体
大概情况
双层床体是为了平滑的创建异形窗体的一个解决方案,找了很多资料,整理了一下。
双层窗体的逻辑是建立在 UpdateLayeredWindow 不能绘制控件的基础上,上层再添加一个专门放置控件的层;这样就可以在上层“控件层”放控件,下层的“皮肤层”绘制异形的窗口。
有两点需要主意:
- 两个窗体的大小和位置的统一,使用 Size 和 Location 来解决;
- 两个窗体的 Z 轴(层次顺序)要准确,使用 Form.Owner 即可解决。
代码
源码下载
如果没有积分,也可以关注我获取哟~
控件层代码:
public partial class MainForm : Form
{
private SkinForm Skin;
public MainForm()
{
InitializeComponent();
ShowInTaskbar = false;//禁止控件层显示到任务栏
FormBorderStyle = FormBorderStyle.None;//设置无边框的窗口样式
}
private void MainForm_Load(object sender, EventArgs e)
{
if (!DesignMode)
{
Skin = new SkinForm(this);//创建皮肤层
BackgroundImage = null;//去除控件层背景
TransparencyKey = BackColor;//使控件层背景透明
Skin.Show();//显示皮肤层
}
}
#region 属性
private bool _skinmobile = true;
[Category("Skin")]
[Description("窗体是否可以移动")]
[DefaultValue(typeof(bool), "true")]
public bool SkinMovable
{
get { return _skinmobile; }
set
{
if (_skinmobile != value)
{
_skinmobile = value;
}
}
}
#endregion
}
皮肤层代码:
partial class SkinForm : Form
{
private MainForm Main;
public SkinForm(MainForm main)
{
InitializeComponent();
SetStyles();//减少闪烁
Main = main;//获取控件层对象
FormBorderStyle = FormBorderStyle.None;//设置无边框的窗口样式
ShowInTaskbar = true;//使控件层显示到任务栏
BackgroundImage = Main.BackgroundImage;//将控件层背景图应用到皮肤层
BackgroundImageLayout = ImageLayout.Stretch;//自动拉伸背景图以适应窗口
Size = Main.Size;//统一大小
Main.Owner = this;//设置控件层的拥有皮肤层
FormMovableEvent();//激活皮肤层窗体移动
SetBits();//绘制半透明不规则皮肤
Location = new Point(Main.Location.X, Main.Location.Y);//统一控件层和皮肤层的位置
}
//减少闪烁代码...(见源码)
//激活皮肤层窗体移动代码...(见源码)
//绘制半透明不规则皮肤代码...(见源码)
}
效果图
参考资料
双层窗体 csdn bbs http://bbs.csdn.net/topics/390769541
双层窗体源码 http://download.csdn.net/download/lyx_520/4921128