窗口奇怪的scrollbar问题

fish_kun 2009-06-04 11:35:55
我添加了窗口的resize事件响应,并将窗口Autoscroll设置为true.

在代码中,我把一些控件添加到窗口上,并设置了它们的位置。

在resize的事件响应中,根据窗口的大小重新排列控件,这些控件是从上到下排列,每行一个控件,先根据窗口的大小算出窗口的中点,在将这些控件居中排列,其中每个控件的上下间隔设置为固定30个像素。

如果计算出的窗口大小比控件本身小,就将控件从窗口的最左边开始排列,这时因为设置了AutoScroll为true,窗口就会出现滚动条。

我用鼠标拖动改变窗口的大小,一切工作正常。

但在一种情况下例外:
窗口的初始状态下,控件可以在窗口上全部显示,没有滚动条,这时将窗口最大化,所有的控件位置也发生变化,都居中排列,这时再将窗口正常化,动作为先点击右上角的最大化按钮,再点击正常化按钮。当窗口正常化后,奇怪的事情发生了,横向的滚动条出现了,其实这时的窗口大小完全可以显示所有控件,横向滚动条根本没有必要出现。如果这时再稍微拖动一下窗口大小,让它变小一点或者变大一点,滚动条又消失了。

不知道大家遇到过这种情况没有,如何解决呢?

我个人对这个问题的一些猜测:
在将窗口最大化后,窗口上的控件为了居中,肯定要向右移动,这时再将窗口正常化,这个过程中窗口发现控件不能完全显示,于是横向滚动条出现,再接着resize的事件响应函数被调用,这些窗口的位置又需要向左移动,但滚动条并不能消失,因为窗口并不知道它实际上需要显示的大小已经发生变化。如果这时再拖动窗口大小,窗口的大小被改变,resize响应函数被调用后窗口需要重新计算是否需要显示ScrollBar,而此时因为控件的位置已经发生改变了,窗口已经可以显示全部控件了,所以滚动条又消失了。

但如何解决这个问题呢?想求教一下大家的高见。
...全文
337 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzuomin 2009-06-06
  • 打赏
  • 举报
回复
在 ResizePanel 中需要先
groupView.AutoScroll = false
调整控件的位置后再
groupView.AutoScroll = true

估计lz就是这个问题,呵呵。
wzuomin 2009-06-06
  • 打赏
  • 举报
回复
Public Class Form1

Private groupView As Panel

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
groupView = New Panel With {.Dock = DockStyle.Fill, .BorderStyle = BorderStyle.FixedSingle, .AutoScroll = True}
AddHandler groupView.Resize, AddressOf ResizePanel
For i As Integer = 0 To 20
Dim btn As New Button With {.Text = "Button" & i.ToString}
groupView.Controls.Add(btn)
Next
Me.Controls.Add(groupView)
End Sub

Private Sub ResizePanel(ByVal sender As Object, ByVal e As EventArgs)
groupView.AutoScroll = False
Dim heightNext As Integer = 3
For Each Control In groupView.Controls
Dim startLeft As Integer = 3
Dim deltaWidth As Integer = (groupView.Width - Control.Width) / 2
If deltaWidth > 0 Then
startLeft = deltaWidth
End If
Control.Left = startLeft
Control.Top = heightNext
heightNext = Control.Bottom + 20
Next
groupView.AutoScroll = True
End Sub

End Class


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Panel groupView;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
groupView = new Panel { Dock = DockStyle.Fill, BorderStyle = BorderStyle.FixedSingle, AutoScroll = true };
groupView.Resize += ResizePanel;
for (int i = 0; i <= 20; i++)
{
Button btn = new Button { Text = "Button" + i.ToString() };
groupView.Controls.Add(btn);
}
this.Controls.Add(groupView);
}

private void ResizePanel(object sender, EventArgs e)
{
groupView.AutoScroll = false;
int heightNext = 3;
foreach (Control control in groupView.Controls)
{
int startLeft = 3;
int deltaWidth = (groupView.Width - control.Width) / 2;
if (deltaWidth > 0)
{
startLeft = deltaWidth;
}
control.Left = startLeft;
control.Top = heightNext;
heightNext = control.Bottom + 20;
}
groupView.AutoScroll = true;
}

}
}


以上代码在 WindowsXp SP3 + VS2008 中调试通过。
wzuomin 2009-06-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 fish_kun 的回复:]
呵呵,LS两位正解,我当时还用groupView.AutoSize = false 和 groupView.AutoSize = true加在Resize事件函数上下。
[/Quote]

10楼11楼是同一个,O(∩_∩)O哈哈~
fish_kun 2009-06-06
  • 打赏
  • 举报
回复
呵呵,LS两位正解,我当时还用groupView.AutoSize = false 和 groupView.AutoSize = true加在Resize事件函数上下。
fish_kun 2009-06-05
  • 打赏
  • 举报
回复
我贴的是我的代码哈,这段代码在拖动窗口大小的时候滚动条都没有问题,唯独在将它最大化后再正常化时滚动条在不该出现的时候出现了。
zenowolf 2009-06-05
  • 打赏
  • 举报
回复
幸苦了楼主。。。写这么多。
fish_kun 2009-06-05
  • 打赏
  • 举报
回复
初始化部分代码:
groupView.Resize+= new EventHandler(ResizePanel);
groupView.AutoScroll = true;

ResizePanel的部分:
private void ResizePanel(object sender, EventArgs e)
{
int heightNext = 3;
foreach (Control control in controls) // controls 是类型为ArrayList的成员变量,它保存此Panel上所有的控件。
{
int startLeft = 3;
int deltaWidth = (groupView.Width - control.Width) / 2;
if (deltaWidth > 0)
{
startLeft = deltaWidth;
}
control.Left = startLeft;
control.Top = heightNext;
heightNext += control.Bottom + 20;
}
}
其中groupView为Form上的一个Panel,它被设置为Fill填充。
groupView.Dock = DockStyle.Fill;
wzuomin 2009-06-05
  • 打赏
  • 举报
回复
把部分代码贴出来,大家看看吧,我觉得这么说很难让人明白的。
呵呵呵
binhu12332100 2009-06-05
  • 打赏
  • 举报
回复
来学习……
ToHai 2009-06-05
  • 打赏
  • 举报
回复
我也来顶顶
aight 2009-06-05
  • 打赏
  • 举报
回复
楼主可以在点击正常化事件的时候判断一下。
帮楼主顶了。
fish_kun 2009-06-05
  • 打赏
  • 举报
回复
C#中窗口正常化事件是哪个呢?

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧