效果图:
最近一直在研究Winfrom上如何添加透明控件,经过各种方法的尝试,终于实现了一个还算可以的实现方案.实现思路就是通过嵌套多层窗体来实现透明效果.
通过设置 BackColor 和 TransparencyKey 属性来实现透明. 也就是下层窗体加载视频流. 上层窗体实现透明控件效果.(可以嵌套多层窗体。窗体设置Opacity属性实现透明度 ,一种透视的效果)
this.BackColor = Color.Black;
this.TransparencyKey = Color.Black;
上层窗体尺寸设置和主窗体大小一致 ,监听LocationChanged和Resize事件 ,实现上层窗体和主窗体联动效果....
1. 设置背景色、文字颜色(不设置颜色,有可能文字不太清晰)等
2. 控件背景可通过 重写 OnPaint 方法绘制,包括点击,移动,拖拽等功能。
3. 背景图的背景色做成透明色
代码片段:
using System;
using System.Drawing;
using System.Windows.Forms;
using TransparentWindowsForms.Properties;
/************************************************************************
* Copyright (c) 2018 All Rights Reserved.
* 创建人: QuJun
* 创建时间:2018/12/27
* 描述: 树形结构
************************************************************************/
namespace TransparentWindowsForms.Control.menutree
{
public partial class MenuTreeList : UserControl
{
private int _menu_button_width = 30;
private int _menu_button_height = 60;
private int _menu_button_point_x = 0;
private int _menu_button_point_y = 0;
private bool _isShowMenu = false;
private bool _isShowMenuButton = true;
private Image _bg_image = Resources.menutree_bg;
private Image _list_bg = Resources.menutree_left_button;
private Image _menu_left_arrow = Resources.menutree_left_close;
private int _menu_left_point_x = 0;
private int _menu_left_point_y = 0;
private string _menu_title = "设备列表";
private TreeView _tree_view = null;
public MenuTreeList()
{
InitializeComponent();
this.Load += MenuTreeList_OnLoad;
this.MouseDown += Form_MouseDown;
}
public string Menu_Title
{
get { return _menu_title; }
set
{
_menu_title = value;
}
}
private void MenuTreeList_OnLoad(object sender, EventArgs e)
{
init();
}
private void init()
{
_tree_view = new TreeView();
_tree_view.Location = new Point(25, 70);
_tree_view.Size = new Size(this.Width - 25 * 2, this.Height - 70 - 50);
_tree_view.Nodes.Add(getTreeNode());
_tree_view.Visible = false;
_tree_view.BorderStyle = BorderStyle.None;
_tree_view.ForeColor = Color.Snow;
_tree_view.ImageList = getImageList();
_tree_view.BackColor = Color.FromArgb(26, 32, 42);
_tree_view.ItemHeight = 20;
this.Controls.Add(_tree_view);
}
private ImageList getImageList()
{
ImageList list = new ImageList();
list.Images.Add("structure", Resources.menutree_structure);
list.Images.Add("carmer", Resources.menutree_videocamera);
return list;
}
private TreeNode getTreeNode()
{
TreeNode treeNode = new TreeNode();
treeNode.Name = "交警大队";
treeNode.Text = "交警大队";
treeNode.ImageIndex = 0;
treeNode.SelectedImageIndex = 0;
//根节点下面的子节点
TreeNode node1 = new TreeNode();
node1.Text = "展现景湾 (3/3)";
node1.ImageIndex = 0;
treeNode.SelectedImageIndex = 0;
TreeNode node2 = new TreeNode();
node2.Text = "警用设备 (3/3)";
node2.ImageIndex = 0;
node2.SelectedImageIndex = 0;
TreeNode node3 = new TreeNode();
node3.Text = "大楼摄像头";
node3.ImageIndex = 1;
node3.SelectedImageIndex = 1;
TreeNode node40 = new TreeNode();
node40.Text = "全景摄像头";
node40.ImageIndex = 1;
node40.SelectedImageIndex = 1;
//将节点添加到根节点中
treeNode.Nodes.Add(node1);
treeNode.Nodes.Add(node2);
treeNode.Nodes.Add(node3);
treeNode.Nodes.Add(node40);
//为第二个子节点1添加子节点
TreeNode childNode1 = new TreeNode();
childNode1.Text = "展现景湾1";
childNode1.ImageIndex = 1;
childNode1.SelectedImageIndex = 1;
TreeNode childNode2 = new TreeNode();
childNode2.Text = "展现景湾2";
childNode2.ImageIndex = 1;
childNode2.SelectedImageIndex = 1;
TreeNode childNode3 = new TreeNode();
childNode3.Text = "展现景湾3";
childNode3.ImageIndex = 1;
childNode3.SelectedImageIndex = 1;
node1.Nodes.Add(childNode1);
node1.Nodes.Add(childNode2);
node1.Nodes.Add(childNode3);
//为第二个子节点2添加子节点
TreeNode childNode4 = new TreeNode();
childNode4.Text = "警用设备1";
childNode4.ImageIndex = 1;
childNode4.SelectedImageIndex = 1;
TreeNode childNode5 = new TreeNode();
childNode5.Text = "警用设备2";
childNode5.ImageIndex = 1;
childNode5.SelectedImageIndex = 1;
TreeNode childNode6 = new TreeNode();
childNode6.Text = "警用设备3";
childNode6.ImageIndex = 1;
childNode6.SelectedImageIndex = 1;
node2.Nodes.Add(childNode4);
node2.Nodes.Add(childNode5);
node2.Nodes.Add(childNode6);
return treeNode;
}
protected override void OnPaint(PaintEventArgs e)
{
_menu_button_point_x = 0;
_menu_button_point_y = 0;
if (_isShowMenuButton)
e.Graphics.DrawImage(_list_bg, new Rectangle(new Point(_menu_button_point_x, _menu_button_point_y), new Size(_menu_button_width, _menu_button_height)));
if (_isShowMenu)
{
e.Graphics.DrawImage(_bg_image, new Rectangle(new Point(0, 0), new Size(this.Width, this.Height)));
_menu_left_point_x = this.Width - _menu_left_arrow.Width - 10;
_menu_left_point_y = 40;
e.Graphics.DrawImage(_menu_left_arrow, new Rectangle(new Point(_menu_left_point_x, _menu_left_point_y), new Size(_menu_left_arrow.Width, _menu_left_arrow.Height)));
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Far;
//字符串的垂直对齐方式
format.LineAlignment = StringAlignment.Center;
Brush bush = new SolidBrush(Color.SkyBlue);//填充的颜色
Font font = new Font("微软雅黑", 11, FontStyle.Bold);
SizeF z = e.Graphics.MeasureString(Menu_Title, font);
e.Graphics.DrawString(Menu_Title, font, bush, new PointF(20 + z.Width, _menu_left_point_y + 10), format);
}
}
private void Form_MouseDown(object sender, MouseEventArgs e)
{
// 菜单按钮点击
if (e.X > _menu_button_point_x && e.X < _menu_button_point_x + _menu_button_width && e.Y > _menu_button_point_y && e.Y < _menu_button_point_y + _menu_button_height)
{
if (_isShowMenuButton)
showPictureBoxList();
return;
}
if (e.X >= _menu_left_point_x && e.X <= _menu_left_point_x + _menu_left_arrow.Width && e.Y >= _menu_left_point_y && e.Y <= _menu_left_point_y + _menu_left_arrow.Height)
{
if (_isShowMenu)
closePictureBoxList();
return;
}
}
private void showPictureBoxList()
{
_isShowMenuButton = false;
_isShowMenu = true;
_tree_view.Visible = true;
Invalidate();
}
private void closePictureBoxList()
{
_isShowMenuButton = true;
_isShowMenu = false;
_tree_view.Visible = false;
Invalidate();
}
}
}
以上纯属个人想法,不喜勿喷 ,欢迎指正。。
Demo包含一些自定义控件(下拉列表,树形列表 , 图片列表等)均可实现透明效果。主窗体是一个海康相机的监控视频。使用时可替换成其他视频。
Demo地址:https://download.csdn.net/download/haiyangyunbao813/11032553
注: 背景图会稍微有一些锯齿.影响美观. 后来使用DSkin实现了下效果.可以完美实现透明控件效果.(唯一美中不足的是DSKIN不是开源的. 若使用,需购买授权码. 请考虑后使用. )
参考文章:https://blog.csdn.net/haiyangyunbao813/article/details/88740404
DSkin实现Demo下载地址:https://download.csdn.net/download/haiyangyunbao813/11049541