I'm making a test program to see how well I can add events to a custom drawn System.Windows.Form.Control object. 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.
Below is the code part of the GUI (the designer is not included, but the key parts should be obvious).
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. Here is code for the usercontrol, Draw 3 or 4 on the form so they can overlap if they move to the right.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With