图片框的可滚动面板,滚动时不重新绘制边框

Scrollable panel of pictureboxes, borders not repainting on scroll

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

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

    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);
    }

这看起来比蹩脚的 Fixed3D borderstyle 好多了,但是只有在使用滚动条的轨道部分(滚动条之外的区域,左侧或右侧)滚动图像时我才会遇到问题。单击并拖动滚动条本身,或使用箭头效果很好(我从面板滚动事件重新绘制,见下文)。但是当单击轨道时,当图片框从滚动到视图之外滚动回来时,边框不会重新绘制。例如,我单击几个缩略图并设置边框:

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

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

    private void panel1_Scroll(object sender, ScrollEventArgs e)
    {
        SetBorders(panel1);
    }

但是点击track时,好像并没有触发Panel的Scroll事件

我忘了说,SetBorders(复数)是另一种方法(我没有在问题中包括这个方法)循环遍历面板中的图片框,对于每个应该重新绘制的图片,它调用 SetBorder (上面包含的方法)并传递给定的图片框...

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

有什么想法吗?

将所有 picboxes paint event 设置为同一个 sub:

pictureBox1.Paint += pictureBox_Paint;
pictureBox2.Paint += pictureBox_Paint;
....
....

之后将picboxes添加到panel:

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

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

在活动中:

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 );

}

无需再使用 panel1_Scroll 事件!