Autor Beitrag
Chiyoko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# (VS 2017)
BeitragVerfasst: Sa 12.11.16 12:06 
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
ausblenden volle Höhe C#-Quelltext
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;
    //this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    //this.SetStyle(ControlStyles.UserPaint, true);
    ResizeRedraw = true;
}

public PaintPanel(bool isMap = false)
{
    _isMap = isMap;
    DoubleBuffered = true;
    //this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    //this.SetStyle(ControlStyles.UserPaint, true);
    ResizeRedraw = true;
          
}

protected override void OnPaint(PaintEventArgs e)
{
    if (_isMap)
    {
        if (BackgroundImage != null)
        {
            var destRect = new Rectangle(00, 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
ausblenden 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.

ausblenden volle Höhe C#-Quelltext
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:
ausblenden 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?
Einloggen, um Attachments anzusehen!
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4429
Erhaltene Danke: 906


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 12.11.16 12:43 
Aus den Bruchstücken ist schwer irgendwas, außer vielleicht allgemein Positionen wie Application.DoEvents an der falschen Stelle könnte problematisch sein, abzuleiten. Versuch das Problem in einem kompilierbaren möglichst kleinen Beispiel nachzustellen. Dann schauen wir da gern mal drauf.
Chiyoko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# (VS 2017)
BeitragVerfasst: Sa 12.11.16 20:35 
Das Problem lag an der Combobox, die ein Usercontrol darstellt.
Klick auf das Panel, auf dem das Usercontrol liegt, rendert alles wie gehabt.

Dann muss ich das Problem auf eine andre weise lösen.