Hallo liebe Community,
ich habe ein spezielles Problem, was den Renderprozess des Panel-Kontextes angeht.
Problembeschreibung:
Nachdem programmatisch die Autoscrollposition des Panels gesetzt wird, blitzt das Hintergrundbild ganz kurz auf, bleibt dann aber schwarz.
Klicke ich dann mit der Maus in die Map, ist die Position wieder 0,0
Code
Panel
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| public PaintPanel() { DoubleBuffered = true; ResizeRedraw = true; }
public PaintPanel(bool isMap = false) { _isMap = isMap; DoubleBuffered = true; ResizeRedraw = true; }
protected override void OnPaint(PaintEventArgs e) { if (_isMap) { if (BackgroundImage != null) { var destRect = new Rectangle(0, 0, Width, Height);
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; e.Graphics.SmoothingMode = SmoothingMode.HighSpeed; e.Graphics.DrawImage(BackgroundImage, destRect, HorizontalScroll.Value, VerticalScroll.Value, Width, Height, GraphicsUnit.Pixel); e.Graphics.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y); } }
base.OnPaint(e); } |
Autoscroll setzen
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| if(x > (panMap.HorizontalScroll.Maximum - panMap.ClientSize.Width)) x = (panMap.HorizontalScroll.Maximum - panMap.ClientSize.Width);
if(y > (panMap.VerticalScroll.Maximum - panMap.ClientSize.Height)) y = (panMap.VerticalScroll.Maximum - panMap.ClientSize.Height);
Application.DoEvents();
Size scrollOffset = new Size(panMap.AutoScrollPosition); panMap.AutoScrollPosition = new Point((x + scrollOffset.Width), y + scrollOffset.Height);
Point p = panMap.AutoScrollPosition;
panMap.Refresh(); panMap.AutoScrollPosition = p; |
Der Panelinhalt besteht aus 4000 Bildern wovon nur Teile gerendert werden, je nachdem, wo sich die Scrollposition befindet.
Wenn Refresh aufgerufen wird, ruft das panMap Panel OnPaint auf und rendert damit den relevanten Teil.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| if(_mapRenderType == MapRenderType.Worldmap) { e.Graphics.ResetTransform(); e.Graphics.ScaleTransform(1.0F, 1.0F); }
Size scrollOffset = new Size(panMap.AutoScrollPosition); int startX = Math.Min(_worldPicCountX, (e.ClipRectangle.Left - scrollOffset.Width) / _worldPicSize); int startY = Math.Min(_worldPicCountY, (e.ClipRectangle.Top - scrollOffset.Height) / _worldPicSize); int endX = Math.Min(_worldPicCountX, (e.ClipRectangle.Right - scrollOffset.Width + _worldPicSize-1) / _worldPicSize); int endY = Math.Min(_worldPicCountY, (e.ClipRectangle.Bottom - scrollOffset.Height + _worldPicSize-1) / _worldPicSize); Image imgPic;
for(int x = startX; x < endX; x++) { for(int y = startY; y < endY; y++) { foreach(var item in Lists.MinimapImagesList) { if(item.Cx == x && item.Cy == y) { if(_bmpMatrix[x, y] == null) { imgPic = string.IsNullOrEmpty(item.Path) ? _blackBmap : Img.LoadBitmap(item.Path); _bmpMatrix[x, y] = new Bitmap(imgPic, _worldPicSize, _worldPicSize); }
e.Graphics.DrawImage(_bmpMatrix[x, y], new Point(x * _worldPicSize + scrollOffset.Width, y * _worldPicSize + scrollOffset.Height)); } } } } |
Beispiel, mit dem das autoscroll funktioniert:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| private void PanMap_MouseMove(object sender, MouseEventArgs e) { if(e.Button == MouseButtons.Left) { Point changePoint = new Point(e.Location.X - _panMapMousePos.X, e.Location.Y - _panMapMousePos.Y); panMap.AutoScrollPosition = new Point(-panMap.AutoScrollPosition.X - changePoint.X, -panMap.AutoScrollPosition.Y - changePoint.Y); SetMapSrollValues(); _panMapMousePos = e.Location; } }
private void SetMapSrollValues() { vScrollbarPanMap.Value = panMap.VerticalScroll.Value; hScrollbarPanMap.Value = panMap.HorizontalScroll.Value; } |
Die externe Scrollbar und dessen Code kann gefunden werden:
www.codeproject.com/...bars-for-Panels-in-C
Habt ihr vielleicht einen Tip?