【问题标题】:Only one Paint event is being called只有一个 Paint 事件被调用
【发布时间】:2014-07-04 10:53:17
【问题描述】:

我的问题是我有 8 个图片框,而其中只有一个会一次调用其绘制方法。

我的代码有点过大,所以我尽量将其缩小到受影响的部分。

我最好的猜测是,这与其说是我的代码中的错误,不如说是对绘制事件如何工作的误解。

我有一个继承自 PictureBox 的类,我正在使用它而不是 Picturebox。唯一的变化是构造函数

using System.Drawing;
using System.Windows.Forms;

public class DrawingSurface : PictureBox
{
    public DrawingSurface(Rectangle bounds) : base() {
        base.Dock = DockStyle.Fill;
        base.SizeMode = PictureBoxSizeMode.Zoom;
        //I set the size and bounds which is probably redundant because 
        //I was trying random things to fix the problem
        base.Size = new Size(bounds.Width, bounds.Height);
        base.Bounds = bounds;
        base.Margin = new Padding(0) ;
        base.BackColor = Color.Transparent;
    }
}


public class MyForm:Form
{
    public MyForm():base()
    {
        base.FormBorderStyle = FormBorderStyle.Sizable;
        base.MaximizeBox = false;
        base.MinimizeBox = false;
        base.Bounds = Screen.PrimaryScreen.Bounds;
    }

}

这是我的主要课程

class Program
{
    static int Main()
    {
        short boardOffsetX, boardOffsetY, trayOffsetX, trayOffsetY;
        MyForm gameImage = null;
        Tray playerTray = null;
        ScrabbleBoard board = null;
        BagOfLetters bag = null;


        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);//this line of code doesn't work either if any of you can spot anything obvious here.  

        //this is my hacky way of centering the images, wouldn't mind you telling me
        //a better way of doing this either.  
        boardOffsetX = (short)(Screen.PrimaryScreen.Bounds.Width/4);
        boardOffsetY = (short)(Screen.PrimaryScreen.Bounds.Height/8);
        trayOffsetX = (short)(Screen.PrimaryScreen.Bounds.Width / 3.3);
        trayOffsetY = (short)(Screen.PrimaryScreen.Bounds.Height / 24);
        try
        {
            gameImage = new MyForm();
            bag = new BagOfLetters();
            board = new ScrabbleBoard(gameImage, new Point(boardOffsetX, boardOffsetY));
            playerTray = new Tray(bag, trayOffsetX, trayOffsetY, gameImage);
            gameImage.ShowDialog();
        }
        finally
        {
             //Dispose all
        }
    }
}

我的图像是这样绘制的。我有一个带有大图像的大类包含 7 个较小的类及其图像。我尝试从我的大班初始化所有内容。

public class Tray{
    private Image TrayImage;
    private DrawingSurface TraySurface;
    private short OffsetY = 0;
    private short OffsetX = 0;
    public List<LB> Tray;

    public Tray(Bag bag, short offsetX, short offsetY, MyForm gameImage)
    {
        Letter tmp;

        //paramater validation

        TrayImage = Image.FromFile(PATHOFTRAY);
        //GetBoundsAsRectangle is just getting the image dimensions as a rectangle
        TraySurface = new DrawingSurface(GetBoundsAsRectangle()) ;
        TraySurface.Location = new Point(offsetX, offsetY);

        this.OffsetX = offsetX;
        this.OffsetY = offsetY;

        do
        {
            tmp = bag.PullLetter();
        }
        while (AddLetter(tmp, gameImage));
        //make this image draw
        TraySurface.Paint += new PaintEventHandler(this.Draw);
        gameImage.Controls.Add(TraySurface);
        TraySurface.SendToBack();
    }


    public bool AddLetter(Letter letter, MyForm gameImage) {
        //argument validation
        Count++;
        letter.PutOnTray(Count, OffsetX, OffsetY);
        gameImage.Controls.Add(letter.GetDrawingSurface());
        if (letterCount >= MAXLETTERS)
        {
            return false;
        }
        return true;
    }


    public void Paint(Object sender, PaintEventArgs drawEvent)
    {
        //paramater validation here
        Rectangle rectangleAreaToDrawImage = new Rectangle(OffsetX,
                                                            OffsetY,
                                                            TrayImage.Width,
                                                            TrayImage.Height);
        // Draw image to screen.
        drawEvent.Graphics.DrawImage(TrayImage, rectangleAreaToDrawImage);
    }
}

public class Letter
{
    private Image LetterImage;
    private DrawingSurface LetterSurface;
    private int PositionOnTray;

    public Letter(char value, String fName) {
        LetterImage = Image.FromFile(fName);
        LetterSurface = new DrawingSurface(GetBoundsAsRectangle());
    }


    public void PutOnTray(short position, short x, short y)
    {
        //validation
        PositionOnTray = position;
        TrayOffsetX = (short)(x + (position*20));
        TrayOffsetY = y;
        IsOnTray = true;
        LetterSurface.Location = new Point(TrayOffsetX, TrayOffsetY);
        LetterSurface.Paint += new PaintEventHandler(this.Draw);
    }
    public void Paint(Object sender, PaintEventArgs drawEvent)
    {
        int x = 0, y = 0;

        //paramater validation here
        x = (TrayOffsetX + (LetterImage.Width * PositionOnTray));
        y = (TrayOffsetY + 6);
        Location = new Rectangle(x,
                                 y,
                                 LetterImage.Width,
                                 LetterImage.Image.Height);
        drawEvent.Graphics.DrawImage(LetterImage, Location);
}

所以基本上托盘有图像,7 个字母也有图像。字母现在被绘制在托盘顶部,但在它们自己的图片框中。我向托盘和字母添加了一个绘制方法,并将它们添加到图片框 Paint thingy。我需要这些字母具有单独的图片框,因为稍后我想添加功能以通过鼠标单击将它们拾取并在屏幕上拖动。

问题是没有调用绘制方法。只是理论上的伪代码,你会怎么画这个?我来自 Java/C/C++ 背景,图形从来都不是我关注的焦点,所以我确信这不是一个错误,而是我的处理方式是错误的。

【问题讨论】:

  • 我认为这是winforms?请添加适当的平台标签! PictureBoxes 上的注释:它们有背景,就像所有控件一样,您可以在其 Paint 事件中绘制它。但他们的主要特点是他们的形象,你可以设置和修改;它负责保持图像始终保持最新状态。那么你在哪里画画呢?图像或背景(如果您有图像集,将或多或少覆盖)?
  • 模糊。字母被添加到表格中。非常不清楚它们与 TraySurface 的关系,您希望将字母添加到 TraySurface 中。使用 Color.Transparent 也从来不是问题,透明度是模拟的,堆叠效果不起作用。
  • 我更新了我的帖子。它是 System.Windows.Forms,所以我假设是 winforms。
  • 我更新了我的帖子。它是 System.Windows.Forms,所以我假设是 winforms。我将尝试在图片框绘制事件中进行绘制,而不是看看是否可行。直到现在我都用图像画了。注释掉透明颜色并没有改变任何东西。老实说,我觉得这只是我应该做的愚蠢的事情,而我不是。我基本上是从我在网上找到的碎片中拼凑出这个图像代码,所以不要太看重它。
  • 我没有任何具体的建议,但我不确定我是否理解您需要特定的绘制处理程序 - 这通常仅在您实现自己的自定义绘图时使用,例如,也许您想要一个绘制背景渐变的控件或想要创建一个不存在的控件(行分隔符控件是 C# 中的常见控件)。为此,我希望您能够使用香草图片框,并将它们设置为您想要的图像,并根据需要移动它们。我可能会从一些简化开始(首先构建你的部件)并从那里重建。

标签: c# winforms graphics


【解决方案1】:

解决方案是删除所有图片框...所有这些事件都可以直接添加到表单中而不会出现问题。我最初认为我需要通过图片框为所有内容提供单独的处理程序,但我错了。似乎 Pictureboxes 的事件部分几乎没有使用,除非在极少数情况下,例如将它们添加到 tablelayoutpanel 时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    • 2019-04-18
    • 2023-03-28
    • 1970-01-01
    • 2012-02-20
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多