什么是,以及如何通过绘制矩形来确定这个奇怪异常的原因?

Posted

技术标签:

【中文标题】什么是,以及如何通过绘制矩形来确定这个奇怪异常的原因?【英文标题】:What is, and how do I determine the cause of this strange exception with drawing a Rectangle? 【发布时间】:2015-10-14 03:23:22 【问题描述】:

我正在尝试在自定义控件的 OnPaint 方法中绘制一个 Rectangle。不是我不知道怎么做,只是这次我试图正确地做(而不是每次调用 OnPaint 时都创建一个新的 Pen)。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SomeNamespace

    public partial class Window : Form
    
        #region Designer Properties
        [Browsable(true), DisplayName("FormBorderColor"), Category("Appearance")]
        public Color FormBorderColor  get; set; 

        [Browsable(true), DisplayName("FormBorderThickness"), Category("Appearance")]
        public float FormBorderThickness  get; set; 

        #endregion

        private Pen formBorderPen;
        private Brush formBorderBrush;
        private Rectangle formBorderRectangle;

        public Window()
        
            InitializeComponent();

            this.DoubleBuffered = true;

            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);

            this.SetStyle(ControlStyles.ContainerControl, true);
            this.SetStyle(ControlStyles.Selectable, true);

            // Initialize Border properties
            formBorderBrush = new SolidBrush(FormBorderColor);
            formBorderPen = new Pen(formBorderBrush, FormBorderThickness);
            formBorderRectangle = new Rectangle(0, 0, this.Width - (int)FormBorderThickness, this.Height - (int)FormBorderThickness);
        

        protected override void OnPaint(PaintEventArgs paint)
        
            switch(this.FormBorderStyle)
            
                // If this FormBorderStyle is set to None, we can either
                // draw our own custom border, or no border at all.
                case FormBorderStyle.None:
                    // Draw Form Border if necessary.
                    Console.WriteLine(FormBorderColor);
                    Console.WriteLine(FormBorderThickness);

                    Console.WriteLine(formBorderBrush);
                    Console.WriteLine(formBorderPen);
                    Console.WriteLine(formBorderRectangle);

                    if(FormBorderThickness >= 1)
                    
                        Console.WriteLine("Hooray?");
                        paint.Graphics.DrawRectangle(formBorderPen, formBorderRectangle);
                    
                    else
                    
                        Console.WriteLine("Can't draw border.");
                    
                    break;
                default:
                    break;
            

            base.OnPaint(paint);
        
    

...但是,我遇到了很多例外情况,我相信这是因为在我期望设置某些值时没有设置它们。但我不知道在哪里设置值。

我将在这里暗中尝试,并假设这些异常被抛出,因为这些对象的值是在构造函数中设置的,但是,我不知道在哪里设置这些价值观。根据我在 MSDN 上看到的情况,我认为我将值设置在正确的位置。


CustomEndCap 异常:

'formBorderPen.CustomEndCap' 抛出类型异常 'System.ArgumentException'

CustomStartCap 异常:

'formBorderPen.CustomStartCap' 抛出类型异常 'System.ArgumentException'

DashPattern 异常:

'formBorderPen.DashPattern' 抛出类型异常 'System.OutOfMemoryException'

我不明白的是,为什么我会得到 这些 异常?我什至不玩 Caps 或 DashPatterns。为什么我手动设置笔和画笔时它们是空的?


【问题讨论】:

【参考方案1】:

对于 FormBorderThickness,您的笔大小可能为零,这会导致您看到的一些问题。

此外,如果您引用 Width 或 Height 等属性,则不应使用表单的构造函数,因为这些尺寸尚未完全确定。您应该为此使用 OnLoad 覆盖。

我个人会创建这些笔并在 Paint 事件中处理它们,将它们保留在本地范围内。那个矩形也一样。

【讨论】:

Pen size 是 1 for FormBorderThickness,因为它是在设计器视图的属性窗格中设置的,当我检查 if(BorderThickness >= 1) it returns true and then _attempts_ to paint on the Control. And, if you ,look at the output window in the screenshot, at the very top (albeit slightly cut-off), you can see a 1` 时 - 这就是 FormBorderThickness 值。 使用 OnLoad 会减慢速度吗?我已经有一段时间避免使用 OnLoad 了,因为当我使用它时,我通常会看到速度明显下降。 @Aston 代码在 OnLoad 方法中运行速度不会变慢。 一定是我当时写的烂代码。感谢您的回答:) 它现在按预期工作。将 = new ... 的东西移到 OnLoad 工作得很好。【参考方案2】:

您说对象的值是空的,但您所做的 Console.WriteLine 表明它们确实具有值.. 并且您显示的异常似乎不是您的应用程序中的异常。这些异常在 Visual Studio 检查器中。因为它试图显示对象的所有成员的值。一些成员可能尚未初始化或处于无效状态,因此 Visual Studio 遇到异常。 . 但这对您的应用程序没有影响,因为您没有使用这些属性。

【讨论】:

是的,也许,但最后,我的矩形没有被绘制出来......所以出了点问题。我将一些东西移到 OnLoad 事件中,现在它工作正常。

以上是关于什么是,以及如何通过绘制矩形来确定这个奇怪异常的原因?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PyQt5 中通过拖放来绘制矩形并调整其形状

java对于绘制的矩形,如何用鼠标双击可以选中这个矩形,并且可以通过方法在举行框中进行文本编辑.

如何在uitableviewcell内绘制一个矩形

如何保持确定的形状区域不被切割?

如何使用 Canvas 创建 3D 图形

如何使用 Canvas 创建 3D 图形