Экран не перерисовывается до конца обработчика событий 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 и используя какой-либо флаг, чтобы указать, что произошли оба требуемых события и можно сделать снимок экрана.,
Кроме того, вы можете заставить его перерисовать: как я могу назвать событие рисования?