C# 图片框的可滚动面板,边框不在滚动上重新绘制

C# 图片框的可滚动面板,边框不在滚动上重新绘制,c#,winforms,scroll,picturebox,C#,Winforms,Scroll,Picturebox,我正在构建一个带有可滚动缩略图的图像查看器。我有一个带有面板的表单,面板上的autoscroll设置为true。我用图片盒加载面板,每个图片盒对应一个文件夹;这些是缩略图,一旦面板中有多个图片框,它们就可以在面板中滚动 我可以单击一个或多个picturebox(缩略图),并在单击的每个picturebox周围放置边框。起初我使用了BorderStyle=BorderStyle.Fixed3D,但这种薄边框是不够的。因此,现在我通过在picturebox上绘制矩形来设置picturebox的边框:

我正在构建一个带有可滚动缩略图的图像查看器。我有一个带有面板的表单,面板上的autoscroll设置为true。我用图片盒加载面板,每个图片盒对应一个文件夹;这些是缩略图,一旦面板中有多个图片框,它们就可以在面板中滚动

我可以单击一个或多个picturebox(缩略图),并在单击的每个picturebox周围放置边框。起初我使用了BorderStyle=BorderStyle.Fixed3D,但这种薄边框是不够的。因此,现在我通过在picturebox上绘制矩形来设置picturebox的边框:

    private void SetBorder(PictureBox pb)
    {
        var color = ColorTranslator.FromHtml("#ff9900");
        var rc = pb.ClientRectangle;
        rc.Inflate(-1, -1);
        ControlPaint.DrawBorder(pb.CreateGraphics(), rc, color, 3, ButtonBorderStyle.Solid, color, 3, ButtonBorderStyle.Solid, color, 3, ButtonBorderStyle.Solid, color, 3, ButtonBorderStyle.Solid);
    }
这看起来比lame Fixed3D borderstyle好得多,但我在使用滚动条的轨迹部分(滚动条外部的区域,左侧或右侧)滚动图像时遇到了问题。单击并拖动滚动条本身,或者使用箭头可以正常工作(我从面板滚动事件重新绘制,请参阅下文)。但是,当单击轨迹时,当图片框从视图中滚回时,边框不会重新绘制。例如,我单击两个缩略图并设置边框:

边框看起来不错,但如果我向右滚动(单击轨迹),然后再向左滚动,覆盖的部分不会重新绘制。例如:

如上所述,单击滚动条箭头或拖动滚动条时,我正在面板滚动事件中重新绘制边框:

    private void panel1_Scroll(object sender, ScrollEventArgs e)
    {
        SetBorders(panel1);
    }
但是,在曲目中单击时,似乎不会引发面板的滚动事件。

我忘了提到,SetBorders(复数)是另一种方法(我在问题中没有包括这个方法),它循环通过面板中的picturebox,对于每个应该重新绘制的,它调用SetBorder(上面包括的方法)并传递给定的picturebox

刚发现使用鼠标滚轮滚动时也存在此问题


有什么想法吗?

将所有Picbox
绘制事件设置为同一个子项:

pictureBox1.Paint += pictureBox_Paint;
pictureBox2.Paint += pictureBox_Paint;
....
....
picbox添加到
面板后

var children = panel1.Controls.OfType<Control>();

foreach( Control child in children ) {
    ( (PictureBox)child ).Paint += pictureBox_Paint;
}

无需再使用
panel1\u Scroll
事件

您的
setboorders
接受参数
picturebox
,但您正在发送一个
面板
!好的,所以我没有提供所有的代码。SetBorders(复数)是另一种在面板中的picturebox中循环的方法,对于每个应该重新绘制的picturebox,它调用SetBorder并传递给定的picturebox…哎呀!我没有注意到。我建议,因为您正在动态创建picbox,所以只需在这些
picbox的
paint
事件中绘制边框即可。如果Picbox的大小相同,则只需一个
绘制事件
private void pictureBox_Paint( object sender, PaintEventArgs e ) {
    PictureBox picbox = (PictureBox)sender;
    var color = ColorTranslator.FromHtml( "#ff9900" );
    var rc = picbox.ClientRectangle;
    rc.Inflate( -1, -1 );

    ControlPaint.DrawBorder( e.Graphics, rc, color, 3, ButtonBorderStyle.Solid, color, 3, 
                             ButtonBorderStyle.Solid, color, 3, ButtonBorderStyle.Solid, 
                             color, 3, ButtonBorderStyle.Solid );

}