C# winform-пользовательский элемент управления не окрашивается при изменении размера формы
Я работаю над базой для небольшой простой программы в стиле игры и использую Form1_Resize для управления масштабом и расположением готовых элементов управления, которые я разместил. В настоящее время они представляют собой просто picturebox и две пустые кнопки для тестирования, однако они масштабируются и работают идеально, когда экран изменяется в этом методе.
Я добавил пользовательский элемент управления для размещения изображений с прозрачностью, и он также отлично работает, однако при изменении размера экрана изображение из пользовательского элемента управления исчезнет. Я знаю, что это связано с тем, что он закрашивается и не перекрашивается, когда размер экрана изменяется. Сообщая ему обновиться в методе form1_Resize, он действительно появляется после завершения изменения размера, но все равно исчезает во время изменения размера. Я перепробовал все, что мог найти, но это все еще в основном ново для меня, и мне не везет.
Вот мои занятия ниже.
Что я уже пробовал:
Форма form1.в CS
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace List_Game { public partial class Form1 : Form { int baseFormWidth = 1280; int baseFormHeight = 720; int baseStartButtonWidth = 250; int baseStartButtonHeight = 100; int baseSettingsButtonWidth = 250; int baseSettingsButtonHeight = 60; // When resized, difference of form size and window size int windowWidthOffset; int windowHeightOffset; //Position of button box to center it when scaling screen int startButtonXOffset; int startButtonYOffset; int settingsButtonXOffset; int settingsButtonYOffset; public Form1() { InitializeComponent(); windowWidthOffset = this.Width - GameWindow.Width; windowHeightOffset = this.Height - GameWindow.Height; } float WidthScale() { return (float)this.Width / (float)baseFormWidth; } float HeightScale() { return (float)this.Height / (float)baseFormHeight; } private void Form1_Resize(object sender, EventArgs e) { GameWindow.Width = this.Width - windowWidthOffset; GameWindow.Height = this.Height - windowHeightOffset; float scaledStartButtonWidth = baseStartButtonWidth * WidthScale(); float scaledStartButtonHeight = baseStartButtonHeight * HeightScale(); StartButton.Width = (int)scaledStartButtonWidth; StartButton.Height = (int)scaledStartButtonHeight; float scaledSettingsButtonWidth = baseSettingsButtonWidth * WidthScale(); float scaledSettingsButtonHeight = baseSettingsButtonHeight * HeightScale(); SettingsButton.Width = (int)scaledSettingsButtonWidth; SettingsButton.Height = (int)scaledSettingsButtonHeight; startButtonXOffset = GameWindow.Width / 2 - StartButton.Width / 2; startButtonYOffset = (int)(GameWindow.Height / 1.44) - StartButton.Height / 2; settingsButtonXOffset = GameWindow.Width / 2 - (SettingsButton.Width / 2); settingsButtonYOffset = GameWindow.Height - (int)(SettingsButton.Height * 1.25); Point startButtonLocation = new Point(startButtonXOffset, startButtonYOffset); Point settingsButtonLocation = new Point(settingsButtonXOffset, settingsButtonYOffset); StartButton.Location = startButtonLocation; SettingsButton.Location = settingsButtonLocation; } private void Settings_Click(object sender, EventArgs e) { } private void Start_Click(object sender, EventArgs e) { } } }
ScreenDrawing.в CS
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace List_Game { abstract public class ScreenDrawing : Panel { public ScreenDrawing() { this.ResizeRedraw = true; } protected Graphics graphics; abstract protected void OnDraw(); protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT return cp; } } protected override void OnPaintBackground(PaintEventArgs pevent) { } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // Update the private member so we can use it in the OnDraw method this.graphics = e.Graphics; // Set the best settings possible (quality-wise) this.graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; this.graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; this.graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; this.graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // Calls the OnDraw subclass method OnDraw(); } } }
DrawControl.в CS
using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace List_Game { class DrawControl : ScreenDrawing { public DrawControl() { this.ResizeRedraw = true; } Image displayedImage = null; int width; int height; Rectangle big; public void SetImage() { if (this.BackgroundImage == null) { displayedImage = global::List_Game.Properties.Resources.StartButton2; } else displayedImage = this.BackgroundImage; } protected override void OnDraw() { SetImage(); // Sets the images' sizes and positions width = displayedImage.Size.Width; height = displayedImage.Size.Height; this.Width = width; this.Height = height; big = new Rectangle(0, 0, width, height); // Draws the two images this.graphics.DrawImage(displayedImage, big); } } }
Hermann Jung
Я принимаю форму 1.GameWindow-это экземпляр DrawControl. Вы обновляете его размер в Form1.Resize и в DrawControl.Рисуйте с разными значениями. Вы никогда не должны обновлять свойства элемента управления в Paint-event.
Взгляните на Form.SetStyle, ControlStyles.AllPaintingInWmPaint и форма.Документация OnPaintBackground. Похоже, вы хотите нарисовать изображение в качестве фона.
Dark_Dragoon
На самом деле нет GameWindow-это просто picturebox по умолчанию, который я использую в качестве фона, который отлично работает. В настоящее время у меня нет никакого кода или чего-либо еще, что изменяло бы размер или местоположение используемого DrawControl. DrawControl будет использоваться для рисования прозрачных изображений поверх игрового окна, которое является фоном. Он прекрасно работает, просто при изменении размера формы он исчезает. Если я добавлю что-то вроде drawControl1.Refresh(); в метод Form1_Resize, то он действительно появится после изменения размера, но пока форма изменяется, она становится невидимой, я предполагаю, что она не окрашивается, пока форма изменяется.
Hermann Jung
Создание ScreenDrawing transparent (CreateParam: WS_EX_TRANSPARENT) вредит внутренней логике порядка видимости. Вы можете исправить это позвонив:
foreach (var drawControl в элементах управления.OfType<DrawControl>()) drawControl.Аннулировать();
или похожий по форме.:
1.) используйте изображение конкретной области (Control.Свойство региона) вместо прозрачности. Видишь ли https://www.codeproject.com/articles/6048/creating-bitmap-regions-for-forms-and-buttons
или 2.)
Обрабатывать событие Paint в элемент управления PictureBox рисовать спрайты. Этот подход потребует некоторого дополнительного кода для аннулирования области рисования при перемещении спрайтов.