六、双层窗体
大概情况
双层床体是为了平滑的创建异形窗体的一个解决方案,找了很多资料,整理了一下。
双层窗体的逻辑是建立在 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