简体   繁体   English

Windows窗体:允许重叠控件的正确方法是什么?

[英]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.

相关问题 如何检查两个控件在Windows窗体中是否重叠 - How to check if two controls are overlapping in Windows Forms 将Windows窗体应用程序带到前台的“正确”方法是什么? - What is the “right” way to bring a Windows Forms Application to the foreground? UI控件在Windows窗体应用程序中重叠和字体问题 - UI Controls Overlapping & Fonts Issue in Windows Forms Application .NET Windows窗体应用程序更新自身的最佳方法是什么? - What's the best way for a .NET windows forms application to update itself? 用于多个控件的Windows窗体右键菜单 - Windows Forms right-click menu for multiple controls 验证.NET Windows窗体的正确方法是什么? - What is the right method of validating .NET Windows Forms? Windows窗体控件装饰 - Windows Forms controls decoration Windows窗体:使用BackgroundImage会减慢窗体控件的绘制速度 - Windows Forms: using BackgroundImage slows down drawing of the Form's controls 在Windows Forms中,最简单的方法是获取放置另一个控件的控件。 - In Windows Forms what's the easiest way to get the control(s) over which another control is placed? 在Windows Phone项目中使用Akavache的LoadImageFromUrl的正确方法是什么? - What's the right way to use Akavache's LoadImageFromUrl in a Windows Phone project?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM