C# 面板向下滚动时会丢失内容

C# 面板向下滚动时会丢失内容,c#,winforms,scroll,panel,paint,C#,Winforms,Scroll,Panel,Paint,我在一个较大的面板内有两个面板。两个内部面板自动调整大小,外部面板自动滚动,以便我可以一起向下滚动两个面板的内容 我使用“绘制”事件在右侧面板上绘制网格线,两个面板上都有标签控件 这一切都很好(也可以调整大小和响应),但当我向下滚动时,会发生一些奇怪的事情 因此,假设我将滚动条处于顶部时看到的东西称为初始状态。然后,当我向下滚动时,这个初始状态的任何内容都不可见,我调整大小/最小化/刷新。。。我的右侧面板(带有网格线和标签)变灰,所有东西都消失了。 只有再次向上滚动并点击初始状态的底部,标签和图

我在一个较大的面板内有两个面板。两个内部面板自动调整大小,外部面板自动滚动,以便我可以一起向下滚动两个面板的内容

我使用“绘制”事件在右侧面板上绘制网格线,两个面板上都有标签控件

这一切都很好(也可以调整大小和响应),但当我向下滚动时,会发生一些奇怪的事情

因此,假设我将滚动条处于顶部时看到的东西称为初始状态。然后,当我向下滚动时,这个初始状态的任何内容都不可见,我调整大小/最小化/刷新。。。我的右侧面板(带有网格线和标签)变灰,所有东西都消失了。

只有再次向上滚动并点击初始状态的底部,标签和图形才会返回。

我知道这可能很难理解,但如果你认为你能提供帮助,请随时要求澄清

初始状态

向下滚动并调整大小/最小化-还原后

当我到达某个初始状态时,一切都会再次出现

右侧面板的喷漆事件(尽管我怀疑它是否有多大用处)

我过去常常删除ResizeEnd事件,然后再添加它。我把它改成了ResizeBegin,因为这对我来说更有意义

private void this_SizeChanged(object sender, EventArgs e)
{
    panelTimeline.Controls.Clear();
    sub = dtPickerEnd.Value - dtPickerStart.Value;
    addDayLabels(sub);

    panelUsers.Controls.Clear();
    addUserLabels();

    panelPlanning.Paint += new PaintEventHandler(panelPlanning_Paint);

    ResumeDrawing(panel1);
    ResumeDrawing(panelTimeline);
    ResumeDrawing(panelPipeLine);
    this.ResumeLayout();

    if (userList.Count > 0)
    {
        panelPlanning.Height = userList.Count * userHeight;
        panelUsers.Height = userList.Count * userHeight;
    }
    if (nrResources == 0)
    {
        nrResources = 10;
    }
    userHeight = panel1.Height / nrResources;
    lastPanelHeight = panel1.Height;

    panelPlanning.Controls.Clear();
    addPlanning();

    this.ResizeBegin += new EventHandler(this_beginResize);
}
当“调整大小”结束时,我使用“规划”面板作为容器面板的高度。这可能是我向下滚动时内容丢失的主要原因。 我将其替换为绘制事件中的代码,以计算高度。我还指定了一个变量lastPanelHeight,用于跟踪下面方法的面板高度。 Maximize和restore事件在实际执行之前在这里被调用,所以我需要知道它们必须恢复到什么位置

protected override void WndProc(ref Message m)
{
    if (m.Msg == 0x0112) // WM_SYSCOMMAND
    {
        // Check your window state here
        if (m.WParam == new IntPtr(0xF030) || m.WParam == new IntPtr(0xF120)) // Maximize event - SC_MAXIMIZE from Winuser.h
        {
            //Same code as the two above combined but with lastPanelHeight as value to do the calculations with
        }
    }
    base.WndProc(ref m);
}
然而,我仍然遇到一些问题。当我调整大小,窗体变大,或者从最大化或最小化状态恢复窗口时,滚动条会以一种奇怪的方式运行。 当它一路向下,形状变大时,它在面板中保持相同的高度,从而向上移动。 在还原时,滚动条始终返回顶部。
有什么想法吗?

经过初步改进(见问题编辑2),我把注意力集中在滚动条上,过了一段时间也开始工作了。诀窍是在调整大小之前跟踪滚动条值和面板高度,并在调整大小之后使用新高度进行计算。滚动位置设置如下,但滚动条仍会显示在另一个位置。这可以通过启用和禁用滚动条来解决。下面是完整的代码(请注意,也有用于最大化和恢复的代码)

///表单的开头调整大小
/// 
/// 
/// 
private void this_beginResize(对象发送方,事件参数e)
{
lastLocation=此.Location;
this.ResizeBegin-=新事件处理程序(this_beginResize);
panelPlanning.Paint-=新的PaintEventHandler(panelPlanning\u Paint);
scrollvalue=panel1.VerticalScroll.Value;
lastHeight=panel1.高度;
这个.SuspendLayout();
SuspendDrawing(时间线);
悬挂式图纸(管道);
悬挂式图纸(面板1);
}
/// 
///在完成窗体大小调整时调用
/// 
/// 
/// 
private void this_SizeChanged(对象发送方,事件参数e)
{
if(this.Location!=lastLocation)
{
lastLocation=此.Location;
返回;
}
panelTimeline.Controls.Clear();
sub=dtPickerEnd.Value-dtPickerStart.Value;
addDayLabels(sub);
panelUsers.Controls.Clear();
addUserLabels();
panelPlanning.Paint+=新的PaintEventHandler(panelPlanning\u Paint);
恢复图纸(面板1);
简历图(时间线);
恢复图纸(管道);
这是resumeloayout();
如果(userList.Count>0)
{
panelPlanning.Height=userList.Count*userHeight;
panelUsers.Height=userList.Count*userHeight;
}
如果(nrResources==0)
{
自然资源=10;
}
userHeight=panel1.高度/nR资源;
panel1.VerticalScroll.Value=scrollvalue*panel1.Height/lastHeight;
panel1.VerticalScroll.Enabled=false;
panelPlanning.Controls.Clear();
addPlanning();
this.ResizeBegin+=新事件处理程序(this_beginResize);
panel1.VerticalScroll.Enabled=true;
panel1.VerticalScroll.Value=scrollvalue*panel1.Height/lastHeight;
}
/// 
///处理最大化和恢复
/// 
/// 
受保护的覆盖无效WndProc(参考消息m)
{
if(m.Msg==0x0112)//WM\u SYSCOMMAND
{
//在这里检查您的窗口状态
if(m.WParam==new IntPtr(0xF030)| | m.WParam==new IntPtr(0xF120))//最大化事件-SC_从Winuser.h最大化
{
this.ResizeBegin-=新事件处理程序(this_beginResize);
panelPlanning.Paint-=新的PaintEventHandler(panelPlanning\u Paint);
scrollvalue=panel1.VerticalScroll.Value;
如果(面板1.高度!=0)
{
lastHeight=panel1.高度;
}
这个.SuspendLayout();
SuspendDrawing(时间线);
悬挂式图纸(管道);
悬挂式图纸(面板1);
panel1.VerticalScroll.Enabled=false;
}
}
基准WndProc(参考m);
if(m.Msg==0x0112)//WM\u SYSCOMMAND
{
//在这里检查您的窗口状态
if(m.WParam==new IntPtr(0xF030)| | m.WParam==new IntPtr(0xF120))//最大化事件-SC_从Winuser.h最大化
{
panelTimeline.Controls.Clear();
sub=dtPickerEnd.Value-dtPickerStart.Value;
addDayLabels(sub);
panelUsers.Controls.Clear();
addUserLabels();
panelPlanning.Paint+=新的PaintEventHandler(panelPlanning\u Paint);
恢复图纸(面板1);
简历图(时间线);
恢复图纸(管道);
th
private void this_SizeChanged(object sender, EventArgs e)
{
    panelTimeline.Controls.Clear();
    sub = dtPickerEnd.Value - dtPickerStart.Value;
    addDayLabels(sub);

    panelUsers.Controls.Clear();
    addUserLabels();

    panelPlanning.Paint += new PaintEventHandler(panelPlanning_Paint);

    ResumeDrawing(panel1);
    ResumeDrawing(panelTimeline);
    ResumeDrawing(panelPipeLine);
    this.ResumeLayout();

    if (userList.Count > 0)
    {
        panelPlanning.Height = userList.Count * userHeight;
        panelUsers.Height = userList.Count * userHeight;
    }
    if (nrResources == 0)
    {
        nrResources = 10;
    }
    userHeight = panel1.Height / nrResources;
    lastPanelHeight = panel1.Height;

    panelPlanning.Controls.Clear();
    addPlanning();

    this.ResizeBegin += new EventHandler(this_beginResize);
}
protected override void WndProc(ref Message m)
{
    if (m.Msg == 0x0112) // WM_SYSCOMMAND
    {
        // Check your window state here
        if (m.WParam == new IntPtr(0xF030) || m.WParam == new IntPtr(0xF120)) // Maximize event - SC_MAXIMIZE from Winuser.h
        {
            //Same code as the two above combined but with lastPanelHeight as value to do the calculations with
        }
    }
    base.WndProc(ref m);
}
/// The beginning of a form resize
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void this_beginResize(object sender, EventArgs e)
{
    lastLocation = this.Location;
    this.ResizeBegin -= new EventHandler(this_beginResize);

    panelPlanning.Paint -= new PaintEventHandler(panelPlanning_Paint);
    scrollvalue = panel1.VerticalScroll.Value;
    lastHeight = panel1.Height;

    this.SuspendLayout();
    SuspendDrawing(panelTimeline);
    SuspendDrawing(panelPipeLine);
    SuspendDrawing(panel1);
}

/// <summary>
/// Called when the form is done resizing
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void this_SizeChanged(object sender, EventArgs e)
{
    if (this.Location != lastLocation)
    {
        lastLocation = this.Location;
        return;
    }

    panelTimeline.Controls.Clear();
    sub = dtPickerEnd.Value - dtPickerStart.Value;
    addDayLabels(sub);

    panelUsers.Controls.Clear();
    addUserLabels();

    panelPlanning.Paint += new PaintEventHandler(panelPlanning_Paint);

    ResumeDrawing(panel1);
    ResumeDrawing(panelTimeline);
    ResumeDrawing(panelPipeLine);
    this.ResumeLayout();

    if (userList.Count > 0)
    {
        panelPlanning.Height = userList.Count * userHeight;
        panelUsers.Height = userList.Count * userHeight;
    }
    if (nrResources == 0)
    {
        nrResources = 10;
    }
    userHeight = panel1.Height / nrResources;

    panel1.VerticalScroll.Value = scrollvalue * panel1.Height / lastHeight;
    panel1.VerticalScroll.Enabled = false;

    panelPlanning.Controls.Clear();
    addPlanning();

    this.ResizeBegin += new EventHandler(this_beginResize);

    panel1.VerticalScroll.Enabled = true;
    panel1.VerticalScroll.Value = scrollvalue * panel1.Height / lastHeight;
}

/// <summary>
/// Handles maximize and restore
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
    if (m.Msg == 0x0112) // WM_SYSCOMMAND
    {
        // Check your window state here
        if (m.WParam == new IntPtr(0xF030) || m.WParam == new IntPtr(0xF120)) // Maximize event - SC_MAXIMIZE from Winuser.h
        {
            this.ResizeBegin -= new EventHandler(this_beginResize);

            panelPlanning.Paint -= new PaintEventHandler(panelPlanning_Paint);
            scrollvalue = panel1.VerticalScroll.Value;

            if (panel1.Height != 0)
            {
                lastHeight = panel1.Height;
            }

            this.SuspendLayout();
            SuspendDrawing(panelTimeline);
            SuspendDrawing(panelPipeLine);
            SuspendDrawing(panel1);

            panel1.VerticalScroll.Enabled = false;
        }
    }

    base.WndProc(ref m);

    if (m.Msg == 0x0112) // WM_SYSCOMMAND
    {
        // Check your window state here
        if (m.WParam == new IntPtr(0xF030) || m.WParam == new IntPtr(0xF120)) // Maximize event - SC_MAXIMIZE from Winuser.h
        {
            panelTimeline.Controls.Clear();
            sub = dtPickerEnd.Value - dtPickerStart.Value;
            addDayLabels(sub);

            panelUsers.Controls.Clear();
            addUserLabels();

            panelPlanning.Paint += new PaintEventHandler(panelPlanning_Paint);

            ResumeDrawing(panel1);
            ResumeDrawing(panelTimeline);
            ResumeDrawing(panelPipeLine);
            this.ResumeLayout();

            if (userList.Count > 0)
            {
                panelPlanning.Height = userList.Count * userHeight;
                panelUsers.Height = userList.Count * userHeight;
            }
            if (nrResources == 0)
            {
                nrResources = 10;
            }
            userHeight = panel1.Height / nrResources;

            panel1.VerticalScroll.Value = scrollvalue * panel1.Height / lastHeight;
            panel1.VerticalScroll.Enabled = false;

            panelPlanning.Controls.Clear();
            addPlanning();

            this.ResizeBegin += new EventHandler(this_beginResize);

            panel1.VerticalScroll.Enabled = true;
            panel1.VerticalScroll.Value = scrollvalue * panel1.Height / lastHeight;
        }
    }
}