C# 在mousesup事件处理程序结束之前,屏幕不会重新绘制

C# 在mousesup事件处理程序结束之前,屏幕不会重新绘制,c#,event-handling,rendering,screenshot,mouseup,C#,Event Handling,Rendering,Screenshot,Mouseup,好吧,我有一个问题,我甚至不确定到底发生了什么。基本上:我有一个鼠标点击按钮的事件。该事件将删除1个按钮,并实际移动屏幕上的所有按钮以填补空白。如果你有两行两个按钮 Button1 Button2 Button3 Button4 你点击按钮1,它会移动最后3个,所以你现在有了 Button2 Button3 Button4 好的,在这个事件处理程序的末尾,它获取一个屏幕截图并保存它(用按钮2-4的新图像替换按钮1-4的先前图像) 事件处理程序如下所示 public void Hand

好吧,我有一个问题,我甚至不确定到底发生了什么。基本上:我有一个鼠标点击按钮的事件。该事件将删除1个按钮,并实际移动屏幕上的所有按钮以填补空白。如果你有两行两个按钮

Button1 Button2
Button3 Button4
你点击按钮1,它会移动最后3个,所以你现在有了

Button2 Button3
Button4
好的,在这个事件处理程序的末尾,它获取一个屏幕截图并保存它(用按钮2-4的新图像替换按钮1-4的先前图像)

事件处理程序如下所示

    public void Handle_Button_MouseUp(object sender, MouseEventArgs e)
    {
         //Get rid of the button that was clicked
         ...some unnecessary to the question code here...

        //Rearrange the remaining buttons to fill the gap
        Rearrange_Buttons_In_Tray(element);

        //Save the screenshot
        imageBox.Image = SavePanel1Screenshot();
    }
截图代码是

    public Image SavePanel1Screenshot()
    {
        int BorderWidth = (this.Width - this.ClientSize.Width) / 2;
        int TitlebarHeight = this.Height - this.ClientSize.Height - BorderWidth;

        Rectangle rect = new Rectangle(0, 0, panel1.Width, panel1.Height);
        Bitmap bmp = new Bitmap(panel1.Width, panel1.Height, PixelFormat.Format32bppArgb);
        Graphics g = Graphics.FromImage(bmp);
        g.CopyFromScreen(this.Left + panel1.Left + BorderWidth, this.Top + panel1.Top + TitlebarHeight, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);

        Image screenShot;

        screenShot = (Image)bmp;
        return screenShot;
    }

public void重新排列托盘中的按钮(int元素)
{
for(int i=element;i
清理出一些不必要的问题部分,以避免混乱。对不起,缩进搞错了。注意:按钮不在面板中,仅在面板顶部。我只是为了测量和美观而使用面板

private void Place_Button_In_Tray(Button button, int element, bool isReArrange)
    {
            button.Width = bigButtonWidth;
            button.Height = bigButtonHeight;

            Image buttonImage = button.Image;

        int numButtonsHoriz = panel1.Width / button.Width;
        int numButtonsVerti = panel1.Height / button.Height;
        int extraSpaceHoriz = (panel1.Width % button.Width) / (numButtonsHoriz);
        int extraSpaceVerti = (panel1.Height % button.Height) / numButtonsHoriz;

        int buttonCount;

        if (!isReArrange)
            buttonCount = buttonList.Count - 1;
        else
            buttonCount = element;

        if ((buttonCount) < numButtonsHoriz)
        {
            button.Location = new Point(panel1MinX + (button.Width * (buttonCount)) + extraSpaceHoriz, (panel1MinY + extraSpaceVerti));

        }
        else
        {
            int newLine = (buttonCount) % numButtonsHoriz;
            button.Location = new Point(panel1MinX + (button.Width * (newLine)) + extraSpaceHoriz, ((panel1MinY + extraSpaceVerti) + (button.Height * ((buttonCount) / 2) - ((buttonCount) % 2))));
        }
private void在托盘中放置按钮(按钮按钮、int元素、bool israrrange)
{
按钮宽度=大按钮宽度;
按钮高度=大按钮高度;
图像按钮图像=按钮图像;
int numButtonsHoriz=panel1.宽度/按钮.宽度;
int numButtonsVerti=面板1.高度/按钮.高度;
int extraSpaceHoriz=(panel1.Width%button.Width)/(numButtonsHoriz);
int extraSpaceVerti=(panel1.Height%button.Height)/numButtonsHoriz;
int按钮计数;
如果(!isArrange)
buttonCount=buttonList.Count-1;
其他的
buttonCount=元素;
如果((按钮计数)
现在我的问题是:图像是一个空白屏幕,不是它没有拍照,而是它在屏幕上看到按钮2-4之前拍照(当我一步一步地浏览程序时,我可以明显地看到这种情况发生。拍摄屏幕截图时,屏幕是完全空白的。只有在拍摄完之后,按钮才会重新出现在屏幕上)!出于某种原因,它们直到事件处理程序完成后才会呈现。一旦事件处理程序中的最后一段代码完成(屏幕截图保存),按钮都会重新出现在各自的位置,尽管在整个过程中按钮的可见性根本没有修改(因此它们在整个过程中都保持可见)

我有点困惑到底发生了什么,更重要的是,在事件处理程序发生后,如何获取屏幕截图。有人对可能发生的事情以及更重要的是,如何获取屏幕截图有什么建议吗

编辑:我的描述有点难以理解。我很抱歉。很难准确地表达我正在尝试做什么以及正在发生什么。下面是一个更简洁、更切题的版本:


基本上,我只是想隐藏4个按钮中的1个。屏幕上的其他3个按钮被移动到新的位置。出于某种原因,当它们被移动时,它们会从屏幕上消失。它们直到鼠标移动功能完成后才重新出现,尽管我从未修改过它们是否可见。我只更改它们的位置。我希望屏幕截图包含这3个按钮,但由于某些原因,它们在整个mouseup功能结束之前不会弹出。因此,我的屏幕截图是一个空屏幕,没有按钮。您描述的内容有点混乱。我单击一个按钮将其隐藏,运行屏幕截图代码,图像没有显示按钮

无论如何,要将屏幕截图“延迟”到调用事件后,您可以尝试使用BeginInvoke:

this.BeginInvoke(new Action(() => { imageBox.Image = SavePanel1Screenshot(); }));
我认为移动控件后需要调用刷新:

if ((buttonCount) < numButtonsHoriz) {
  button.Location = new Point(panel1MinX + (button.Width * (buttonCount)) + extraSpaceHoriz, (panel1MinY + extraSpaceVerti));
} else {
  int newLine = (buttonCount) % numButtonsHoriz;
  button.Location = new Point(panel1MinX + (button.Width * (newLine)) + extraSpaceHoriz, ((panel1MinY + extraSpaceVerti) + (button.Height * ((buttonCount) / 2) - ((buttonCount) % 2))));
}
panel1.Refresh();
if((buttonCount)
您正在UI线程中完成工作。请参阅。如果可以,我建议您将屏幕截图移动到后台线程

您可能还需要等待按钮渲染完成,或者使用100毫秒左右的睡眠时间,或者通过调查事件并使用某种标志指示所需事件已经发生,并且可以拍摄屏幕截图


或者,您可以强制它重新绘制:

,只要您只需要自己形式的像素

private void button1_Click(object sender, EventArgs e)
{
    //Button magic
    button1.Visible = false;
    button2.Location = button1.Location;

    Bitmap bmp = new Bitmap(this.Width, this.Height);

    this.DrawToBitmap(bmp, new Rectangle(0, 0, this.Width, this.Height));

    pictureBox1.Image = bmp;
    //or do whatever you want with the bitmap
}

你需要屏幕截图,还是你的表单的图像?我表单的一部分的图像。按钮位于面板顶部(不在面板内。面板仅用于测量和美观)。我所做的就是抓取一个“屏幕截图”正常情况下,它会显示所有按钮。在这种情况下,按钮消失,直到事件处理程序中的所有代码完成后才重新出现(包括屏幕截图代码).因此,当拍摄面板图像时,没有按钮可供拍照!抱歉,描述不明确。这是一个很难描述的场景。基本上,我只是tr
private void button1_Click(object sender, EventArgs e)
{
    //Button magic
    button1.Visible = false;
    button2.Location = button1.Location;

    Bitmap bmp = new Bitmap(this.Width, this.Height);

    this.DrawToBitmap(bmp, new Rectangle(0, 0, this.Width, this.Height));

    pictureBox1.Image = bmp;
    //or do whatever you want with the bitmap
}