2

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

我使用paint事件在我的右侧面板上绘制网格线,并且两者都有标签控件。

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

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

只有当我再次向上滚动并到达初始状态的底部时,标签和图形才会返回。

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

初始状态 初始状态

向下滚动并调整大小/最小化后 - 恢复... 向下滚动并调整大小/最小化后 - 恢复...

当我到达初始状态的东西时,一切都会再次出现

当我到达初始状态的东西时,一切都会再次出现

右侧面板的绘制事件(虽然我怀疑它会有多大用处)

private void panelPlanning_Paint(object sender, PaintEventArgs e)
    {
        for (int i = 0; i <= sub.Days + 1; i++)
        {
            if (toolStripButtonGrid.CheckState == CheckState.Checked)
            {
                if (vertGrid)
                {
                    if (dashedVert)
                    {
                        Pen blackPen = new Pen(Color.FromArgb(50, 0, 0, 0), 1);
                        blackPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                        e.Graphics.DrawLine(blackPen, i * labelDaysWidth, 0, i * labelDaysWidth, panelPlanning.Height);
                    }
                    else
                    {
                        Pen blackPen = new Pen(Color.FromArgb(50, 0, 0, 0), 1);
                        e.Graphics.DrawLine(blackPen, i * labelDaysWidth, 0, i * labelDaysWidth, panelPlanning.Height);
                    }
                }
            }
        }

        for (int i = 0; i < userList.Count; i++)
        {
            if (horGrid && toolStripButtonGrid.CheckState == CheckState.Checked)
            {
                if (dashedHor)
                {
                    Pen blackPen = new Pen(Color.FromArgb(50, 0, 0, 0), 1);
                    blackPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                    e.Graphics.DrawLine(blackPen, 0, i * userHeight, panelPlanning.Width, i * userHeight);
                }
                else
                {
                    Pen blackPen = new Pen(Color.FromArgb(50, 0, 0, 0), 1);
                    e.Graphics.DrawLine(blackPen, 0, i * userHeight, panelPlanning.Width, i * userHeight);
                }
            }
        }

        for (int i = 0; i <= sub.Days + 1; i++)
        {
            if (dtPickerStart.Value.AddDays(i) == DateTime.Today)
            {
                Pen blackpen = new Pen(Color.Black, 3);
                e.Graphics.DrawLine(blackpen, i * labelDaysWidth + labelDaysWidth / 2, 0, i * labelDaysWidth + labelDaysWidth / 2, panelPlanning.Height);
            }
        }

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

编辑

https://www.dropbox.com/sh/p4k9zilmy5pq6ev/RpBEe05B3j

解决方案的简化版本给出了同样的问题。

编辑 2

我已经能够解决大部分问题。下面是我更改的一些代码(要查看我更改的内容,您可以查看上面的 Dropbox 链接进行比较。

private void this_beginResize(object sender, EventArgs e)
{
    this.ResizeBegin -= new EventHandler(this_beginResize);

    panelPlanning.Paint -= new PaintEventHandler(panelPlanning_Paint);

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

我曾经删除 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 来跟踪下面方法的面板高度。最大化和恢复事件在它们实际执行之前在这里被调用,所以我需要知道它们必须恢复到什么。

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

但是,我仍然遇到问题。当我调整大小并且表单变大或从最大化或最小化状态恢复窗口时,滚动条会以一种奇怪的方式运行。当它一直向下并且表格变大时,它在面板中保持相同的高度,从而向上移动。在恢复时,滚动条总是回到顶部。 有任何想法吗?

4

1 回答 1

1

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

/// 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;
        }
    }
}
于 2013-05-02T09:16:02.530 回答