精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。
最近给上市公司完成项目里,有个边缘阴影的UI效果,甲方是以网页形式参考出的UI图,而WinForm形式和网页形式差的十万八千里,实现阴影很麻烦,特别是在复杂的环境里。
网页和Windows的WPF是整体渲染,而WinForm一般是控件窗口自己负责,所以窗口外的区域控制不了,很麻烦,所以一般开发人员看到WinForm边缘阴影、控件边缘阴影和Panel边缘阴影都会头疼,本文后面内容是翻译内容,国外的开发人员的反应也是很头疼,回答的人是驴唇不对马嘴,有些跑题。不过里面的代码的精神值得学习,用UI库实现阴影是个方式,用GraphicsPath路径的技巧,是文章里两个要点。
下面是翻译内容:
我有一个包含其他控件的可移动面板。我想给面板添加一个 DropShadow 效果让它看起来不错,所以我使用了以下代码:
- private DevExpress.Utils.FormShadow.PopupFormShadow ShadowNew = new DevExpress.Utils.FormShadow.PopupFormShadow();
- //Assigned the panel
- ShadowNew.Form = panelControl1;
隐藏阴影的代码是:
- ShadowNew.Form = null;
这很好用,直到我滚动。面板的某些部分不可见,这是正常的,但该部分的阴影仍然可见。我现在要做的是寻找一种方法来检测使用滚动时面板或面板的一部分何时不可见,以便我可以隐藏阴影,并且当面板完全可见时显示阴影。
任何建议
我正在寻找一个替代的阴影,但没有什么比这更好的了。
真诚的问候,
我可以在这里找到 VB 代码中的解决方案:showthread.php
部分 C# 代码是:
- // This will verify if the right side of the panel is not in the forms viewable area and will hide the shadow, else it will show it.
- Rectangle myBounds = this.ClientRectangle;
- if (myBounds.Right < panelControl1.Right)
- {
- ShadowNew.Form = null;
- }
- else
- {
- ShadowNew.Form = panelControl1;
- }
您可以尝试使用GraphicsPath绘制平滑阴影。
这是您可以参考的测试 coed 示例。
- public Form1()
- {
- InitializeComponent();
- shadowControls.Add(panel1);
- this.Refresh();
- }
- List<Control> shadowControls = new List<Control>();
- Bitmap shadowBmp = null;
- Point PanelMouseDownLocation;
- private void panel1_MouseDown(object sender, MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left) PanelMouseDownLocation = e.Location;
- }
- private void panel1_MouseMove(object sender, MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- panel1.Left += e.X - PanelMouseDownLocation.X;
- panel1.Top += e.Y - PanelMouseDownLocation.Y;
- this.Refresh();
- }
- }
- private void Form1_Paint(object sender, PaintEventArgs e)
- {
- if (shadowBmp == null || shadowBmp.Size != this.Size)
- {
- shadowBmp?.Dispose();
- shadowBmp = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb);
- }
- foreach (Control control in shadowControls)
- {
- using (GraphicsPath gp = new GraphicsPath())
- {
- gp.AddRectangle(new Rectangle(control.Location.X, control.Location.Y, control.Size.Width, control.Size.Height));
- DrawShadowSmooth(gp, 100, 60, shadowBmp);
- }
- e.Graphics.DrawImage(shadowBmp, new Point(0, 0));
- }
- }
- private static void DrawShadowSmooth(GraphicsPath gp, int intensity, int radius, Bitmap dest)
- {
- using (Graphics g = Graphics.FromImage(dest))
- {
- g.Clear(Color.Transparent);
- g.CompositingMode = CompositingMode.SourceCopy;
- double alpha = 0;
- double astep = 0;
- double astepstep = (double)intensity / radius / (radius / 2D);
- for (int thickness = radius; thickness > 0; thickness--)
- {
- using (Pen p = new Pen(Color.FromArgb((int)alpha, 0, 0, 0), thickness))
- {
- p.LineJoin = LineJoin.Round;
- g.DrawPath(p, gp);
- }
- alpha += astep;
- astep += astepstep;
- }
- }
- }
对于可移动控件(任何控件),请参阅以下代码项目文章。该类还允许记住/恢复位置。我没有提到实际的面板,因为它是我没有的 DevExpress 第三方库,但应该可以正常工作。
- ControlMoverOrResizer.Init(shadowPanel1);