C#:Windows窗体:可能会导致Invalidate()不重绘?
发布时间:2020-12-15 06:50:11 所属栏目:百科 来源:网络整理
导读:我正在使用 Windows窗体.很长一段时间,pictureBox.Invalidate();努力使屏幕重绘.但是,现在不行,我不知道为什么. this.worldBox = new System.Windows.Forms.PictureBox();this.worldBox.BackColor = System.Drawing.SystemColors.Control;this.worldBox.Bord
我正在使用
Windows窗体.很长一段时间,pictureBox.Invalidate();努力使屏幕重绘.但是,现在不行,我不知道为什么.
this.worldBox = new System.Windows.Forms.PictureBox(); this.worldBox.BackColor = System.Drawing.SystemColors.Control; this.worldBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.worldBox.Location = new System.Drawing.Point(170,82); this.worldBox.Name = "worldBox"; this.worldBox.Size = new System.Drawing.Size(261,250); this.worldBox.TabIndex = 0; this.worldBox.TabStop = false; this.worldBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.worldBox_MouseMove); this.worldBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.worldBox_MouseDown); this.worldBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.worldBox_MouseUp); 在我的代码中被称为适当地画出世界: view.DrawWorldBox(worldBox,canvas,gameEngine.GameObjectManager.Controllers,selectedGameObjects,LevelEditorUtils.PREVIEWS); View.DrawWorldBox: public void DrawWorldBox(PictureBox worldBox,Panel canvas,ICollection<IGameObjectController> controllers,ICollection<IGameObjectController> selectedGameObjects,IDictionary<string,Image> previews) { int left = Math.Abs(worldBox.Location.X); int top = Math.Abs(worldBox.Location.Y); Rectangle screenRect = new Rectangle(left,top,canvas.Width,canvas.Height); IDictionary<float,ICollection<IGameObjectController>> layers = LevelEditorUtils.LayersOfControllers(controllers); IOrderedEnumerable<KeyValuePair<float,ICollection<IGameObjectController>>> sortedLayers = from item in layers orderby item.Key descending select item; using (Graphics g = Graphics.FromImage(worldBox.Image)) { foreach (KeyValuePair<float,ICollection<IGameObjectController>> kv in sortedLayers) { foreach (IGameObjectController controller in kv.Value) { // ... float scale = controller.View.Scale; float width = controller.View.Width; float height = controller.View.Height; Rectangle controllerRect = new Rectangle((int)controller.Model.Position.X,(int)controller.Model.Position.Y,(int)(width * scale),(int)(height * scale)); // cull objects that aren't intersecting with the canvas if (controllerRect.IntersectsWith(screenRect)) { Image img = previews[controller.Model.HumanReadableName]; g.DrawImage(img,controllerRect); } if (selectedGameObjects.Contains(controller)) { selectionRectangles.Add(controllerRect); } } } foreach (Rectangle rect in selectionRectangles) { g.DrawRectangle(drawingPen,rect); } selectionRectangles.Clear(); } worldBox.Invalidate(); } 在这里我可以做错什么 解决方法
要理解这一点,您必须对操作系统级别的工作方式有所了解.
Windows控件是为响应WM_PAINT消息而绘制的.当他们收到这个消息时,他们绘制自己的哪一部分已经被无效.特定控制可以被无效,并且控制的特定区域可以被无效,这一切都是为了尽量减少重新绘制的量. 最终,Windows会看到一些控件需要重画,并向他们发出WM_PAINT消息.但是,只有在处理完所有其他消息后才能执行此操作,这意味着Invalidate不会强制立即重绘.在技??术上刷新应该,但并不总是可靠的. (更新:这是因为刷新是虚拟的,并且有一些控件在野外覆盖此方法与不正确的实现.) 有一种方法通过发出WM_PAINT消息强制立即绘制,即 control.Invalidate(); control.Update(); 即使UI仍在处理消息,这将始终重绘控件,无论发生了什么.从字面上来说,我相信它使用SendMessage API而不是PostMessage,它强制绘画同步完成,而不是在长消息队列的末尾将它们折腾. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容