9

カスタム描画 System.Windows.Form.Control オブジェクトにイベントをどれだけ追加できるかを確認するためのテスト プログラムを作成しています。これでうまくいけば、後でもっと高度なものを作ることができます。

私が抱えている問題は、添付の画像を扱っています。2 つの円を意図的に近づけて描きました。目標は、1 つの円を別の円に重ねることです。このテスト プログラムでは、どの円がどの円に重なるかは気にしません。でも、角が気になる。

突き出た角ではなく、2 つの円が適切に重なり合っていることを願っています。

上の画像は、中央の円が左の円に埋もれていることを示していますが、左の円も角を描き、中心の円を覆っています。それらのコーナーを非表示にするか、少なくとも透明にしたいと考えています。コントロールを透明にする方法があることを読みましたが、BackColor で Color.Transparent を使用すると、ペイント パネルの色と一致するのではなく、何らかの理由で黒くなりました。

以下は 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) });
        }
    }
}

以下はカスタムサークルです。

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);
        }
    }
}

この情報を念頭に置いて、円の角が表示されないようにする方法、またはこれを回避する方法を見つけるにはどうすればよいですか?

4

1 に答える 1

3

メインフォーム form1 に入れるだけでOK。コードは必要ありません。これはユーザーコントロールのコードで、フォーム上に 3 または 4 を描画して、右に移動した場合にオーバーラップできるようにします。

それからそれらをクリックしてください!非効率な点もありますが、赤ちゃんが泣いているので行かなければなりません。独自の保持オブジェクト エディタを作成するよりも優れています。

ここに画像の説明を入力

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
于 2012-12-27T22:49:36.743 に答える