只有一个绘图事件被调用。

3
我的问题是我有8个pictureboxes,但每次只有一个会调用它们的绘制方法。
我的代码有点长,所以我尽可能地缩小了受影响的部分。
我最好的猜测是这不是我的代码中的一个错误,而是对绘制事件如何工作的误解。
我有一个从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个字母也有图片。目前字母是在自己的picturebox里绘制的,但是会被放在托盘之上。我向托盘和字母添加了一个绘制方法,并将它们添加到pictureboxes的画板中。我需要字母具有单独的picturebox,因为以后我想添加功能,使它们可以通过鼠标点击进行拖动。

问题在于,绘图方法没有被调用。纯理论上,你会如何绘制这个东西?我来自Java/C/C++背景,图形从来不是我的重点,所以我确定它不是错误,而是我的做法不正确。


1
我猜这是WinForms?请添加适当的平台标签!关于 PictureBoxes 的说明:它们有一个背景,就像所有控件一样,您可以在其 Paint 事件中绘制。但它们的主要特点是它们的图像,您可以设置和修改它;它会自己处理保持图像始终更新的工作。那么你在哪里画?在图像上还是背景上(如果您设置了图像,则背景将更多或更少被覆盖)? - TaW
1
我没有具体的建议,但我不确定你需要特定的绘图处理程序的原因 - 这通常只用于实现自定义绘图,例如,也许你想要一个绘制背景渐变的控件或者想要创建一个不存在的控件(在C#中,线分隔符控件是常见的)。为此,我希望您能够使用普通的图片框,并将它们设置为所需的图像,并根据需要移动它们。我建议您从简化开始(首先构建您的部件),然后再进行重建。 - antiduh
如果我可以让图像在我指定的特定位置绘制,那么我的图片就不需要自己的绘画处理程序。我唯一关心的是,这些图像最终能够拥有鼠标处理程序,并且按照我事先指定的某种方式在x/y宽度/高度位置上进行绘制。如果你有其他方法来实现这个目标,那么这可能就是答案。 - user3796261
我认为我有一个答案,但我不知道是否能够获得所需的所有功能。现在我正在删除所有的图片框并直接将绘制事件添加到表单中。这样可以按照我想要的方式进行绘制,但是以后我还能否添加鼠标功能呢?比如我想能够拾取图像并移动它们? - user3796261
你可能需要将样式设置为自绘,这将确保每次调用绘制方法。同时使用双缓冲来避免任何闪烁问题。 - pushpraj
显示剩余4条评论
1个回答

0
解决方案是删除所有的图片框... 所有这些事件都可以直接添加到表单中而不会出现问题。我最初认为需要通过图片框提供单独的处理程序来处理所有事情,但我错了。似乎图片框的事件部分几乎没有被使用,除非在像将它们添加到表格布局面板等罕见情况下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接