[英]Windows Forms: What's the right way to allow overlapping Controls?
I'm making a test program to see how well I can add events to a custom drawn System.Windows.Form.Control object. 我正在制作一个测试程序,看看我能将事件添加到自定义绘制的System.Windows.Form.Control对象中。 Should I do well with this, then I can make something more advanced for later.
如果我能做好这件事,那么我可以为以后制作更先进的东西。
The issue I'm having deals with the attached image. 我正在处理附加图像的问题。 I have drawn two circles purposefully close to each other.
我有目的地画了两个圈子。 The goal is to have one circle overlap another.
目标是让一个圆圈与另一个圆圈重叠。 For the purpose of this test program, I do not care which circle overlaps which.
出于本测试程序的目的,我不关心哪个圆圈重叠哪个。 I do, however, care about the corners.
但是,我确实关心角落。
The image above shows that the center circle is buried by the left circle, but the left circle is also drawing the corners and covering the center circle with them. 上图显示中心圆被左圆圈掩埋,但左圆也是绘制角落并用它们覆盖中心圆。 I'm hoping to hide those corners, or at least make them transparent.
我希望隐藏这些角落,或者至少让它们变得透明。 I did read that there is a way to make a control transparent , but using Color.Transparent on the BackColor was giving me black for some reason instead of matching up with the paint panel's color.
我确实读过有一种方法可以使控件透明 ,但在BackColor上使用Color.Transparent会因为某些原因而给我黑色,而不是与画面板的颜色相匹配。
Below is the code part of the GUI (the designer is not included, but the key parts should be obvious). 下面是GUI的代码部分(设计器不包括在内,但关键部分应该是显而易见的)。
namespace PaintingFirstAttempt
{
using System;
using System.Drawing;
using System.Windows.Forms;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void BtnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void BtnClear_Click(object sender, EventArgs e)
{
Graphics g1 = this.paintPanel.CreateGraphics();
g1.Clear(this.paintPanel.BackColor);
g1.Dispose();
}
private void PaintPanel_MouseDown(object sender, MouseEventArgs e)
{
this.paintPanel.Controls.Add(new EventableCircle { Location = new Point(e.X - 16, e.Y - 16), Size = new Size(32, 32) });
}
}
}
Below is the custom circle. 以下是自定义圈子。
namespace PaintingFirstAttempt
{
using System;
using System.Drawing;
using System.Windows.Forms;
public class EventableCircle : Control
{
public EventableCircle()
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
// this.BackColor = Color.Transparent;
}
private static SolidBrush fillColor = new SolidBrush(Color.Red);
protected override void OnClick(EventArgs e)
{
MessageBox.Show("TODO: Bring up a combo box on right click.");
}
private void DrawCircle(Pen pen)
{
Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
g.FillRectangle(new SolidBrush(Color.Transparent), 0, 0, 32, 32);
g.FillEllipse(fillColor, 0, 0, 32, 32);
g.DrawEllipse(pen, 0, 0, 32, 32);
g.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
this.DrawCircle(Pens.Black);
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.DrawCircle(Pens.Blue);
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.DrawCircle(Pens.Black);
}
}
}
With this information in mind, how do I either get the corners of the circles to not show, or find a way to work around this? 记住这些信息,我如何让圈子的角落不显示,或者找到解决这个问题的方法?
OK just put in a mainform form1, doesn't need any code. 好吧只需输入一个mainform form1,不需要任何代码。 Here is code for the usercontrol, Draw 3 or 4 on the form so they can overlap if they move to the right.
这是用户控件的代码,表单上的Draw 3或4,如果它们向右移动,它们可以重叠。
Then click on them! 然后点击它们! There are inefficiencies, but the baby's crying and I have to go, and it beats making your own retained object editor!
效率低下,但宝宝哭了,我得走了,它打败了你自己的保留对象编辑器!
Public Class linectl
Public Sub DrawMe(ByVal g As Graphics, ByVal otherctl As Control)
Dim where As New Rectangle(otherctl.Left - Left, otherctl.Top - Top, otherctl.Width - 1, otherctl.Height - 1)
g.FillEllipse(Brushes.Red, where)
g.DrawEllipse(Pens.Black, where)
End Sub
Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaintBackground(e)
DrawMe(e.Graphics, Me)
drawneighbors()
End Sub
Private Sub linectl_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
Me.Left += 10
End Sub
Private Sub linectl_MoveResize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move, Me.Resize
If Parent IsNot Nothing Then
For Each c In From ctl In Parent.Controls Where TypeOf ctl Is linectl Select CType(ctl, linectl)
Using g = c.CreateGraphics
g.Clear(c.BackColor)
c.DrawMe(g, c)
c.drawneighbors()
End Using
Next
End If
End Sub
Public Sub drawneighbors()
If Parent IsNot Nothing Then
Dim ctls = (From ctl In Parent.Controls Where TypeOf ctl Is linectl Let c = CType(ctl, linectl) _
Select New With {.ctl = c, _
.rect = New Rectangle(c.Left, c.Top, c.Width, c.Height)}).ToArray.Reverse
For Each ctl In ctls
Dim ctl_unclosed = ctl
For Each ictl In (From c In ctls Where ctl_unclosed.rect.IntersectsWith(c.rect))
Using g = ictl.ctl.CreateGraphics
ictl.ctl.DrawMe(g, Me)
End Using
Using g = Me.CreateGraphics
Me.DrawMe(g, ictl.ctl)
End Using
Next
Next
End If
End Sub
End Class
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.