Экран не перерисовывается до конца обработчика событий mousesup

Хорошо, у меня проблема, я даже не уверен, что именно происходит. В основном: у меня есть событие mouseup для нажатия на кнопку. Это событие удалит 1 кнопку и физически переместит все кнопки на экране, чтобы заполнить пробел. Так что если у вас есть 2 ряда по 2 кнопки

Button1 Button2
Button3 Button4

и вы нажимаете кнопку 1, он перемещает последние 3, так что теперь у вас есть

Button2 Button3
Button4

Итак, в конце этого обработчика событий он делает снимок экрана и сохраняет его (заменяя предыдущее изображение кнопок 1-4 новым изображением кнопок 2-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 Rearrange_Buttons_In_Tray(int element)
    {
        for (int i = element; i < buttonList.Count; i++)
        {
            Place_Button_In_Tray(buttonList[i].buttonSaved, i, true);
            buttonList[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))));
        }

А теперь моя проблема: изображение пустого экрана. Дело не в том, что он не делает снимок - он делает снимок до того, как кнопки 2-4 видны на экране (я могу видеть, как это происходит, когда я прохожу программу. Во время снятия снимка экрана экран полностью пустым. Только после этого кнопки снова появляются на экране)! По какой-то причине они не рендерится, пока ПОСЛЕ завершения обработчика событий. После того, как будет завершен последний фрагмент кода в обработчике событий (сохранение снимка экрана), все кнопки снова появляются в своих соответствующих местах, несмотря на то, что видимость кнопок не изменяется вообще в течение всего этого процесса (таким образом, они остаются видимыми все время).

Я немного сбит с толку относительно того, что именно происходит, и, что более важно, как получить этот скриншот после того, как обработчик события произойдет. >_> Есть ли у кого-нибудь предложения о том, что может происходить и, что более важно, как получить этот скриншот?

РЕДАКТИРОВАТЬ: мое описание несколько трудно понять. Я действительно сожалею. Трудно точно сформулировать, что я пытаюсь сделать и что происходит. Вот более компактная и конкретная версия:

По сути, я только пытаюсь скрыть 1 кнопку из 4. Остальные 3 на экране перемещены в новые места. По какой-то причине, когда они перемещаются, они исчезают с экрана. Они не появляются, пока не завершится функция mouseup, несмотря на то, что я никогда не изменял, видимы они или нет. Я только меняю их местоположение. Я хочу, чтобы на скриншоте содержались эти 3 кнопки, но по какой-то причине они не возвращаются к существованию, пока не закончится вся функция mouseup. >_> Итак, мой скриншот - пустой экран, лишенный кнопок

3 ответа

Решение

Это немного сбивает с толку то, что вы описываете. Я нажал кнопку, чтобы скрыть ее, запустить код снимка экрана, и изображение не показывало кнопку.

В любом случае, чтобы "задержать" снимок экрана после вызова события, вы можете попробовать использовать BeginInvoke:

this.BeginInvoke(new Action(() => { imageBox.Image = SavePanel1Screenshot(); }));

Я думаю, что вам нужно вызвать Refresh после перемещения ваших элементов управления:

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();

До тех пор, пока вам нужны только пиксели вашей собственной формы...

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
}

Вы делаете свою работу в потоке пользовательского интерфейса. См. Как заставить кнопки, TextBoxes перерисовываться в форме после закрытия MessageBox в C#. Я бы посоветовал вам перенести скриншот в фоновую ветку, если можете.

Возможно, вам также придется подождать, пока кнопки не будут отрисованы, либо с помощью тупой целесообразности сна в течение 100 мс или около того, либо исследуя событие Paint и используя какой-либо флаг, чтобы указать, что произошли оба требуемых события и можно сделать снимок экрана.,

Кроме того, вы можете заставить его перерисовать: как я могу назвать событие рисования?

Другие вопросы по тегам