返回首页

{S0}简介
时,我一直在寻找一种简单的方式展现在我的程序收集的信息。搜索的时候,我总是结束在ListView中显示的信息。有一天,我发现了一个关于一个多行的ListBox的代码项目上的文章在这里,但并没有真正解决问题,显示的数据,如地址集合。因此,我开始写一个UserControl,这应该很容易使用,解决我的需求。也许这是对他人有益的,太... ...背景
我首先想到的是:容易... ...一个UserControl,使其滚动,并添加与DockStyle.Top每个分控。其余的UserControl本身和框架。
OK,5分钟后的第一个版本是开始。加入100控制(我创建了一个地址控制显示名称,街道,邮编,城市和电话)花了大约17秒。没有好主意...一些测试后(禁用DockStyle等),我从头开始。唯一等于第一种方法 - 它仍然是一个UserControl。速度...
下一步是思考方法仍然显示项目,但不会采取秒钟时间才能生成列表。解决的办法是像一个quot; virtualquot;可见列表。这意味着,在UserControl持有要显示的控件的列表,并重建显示每次控制滚动的项目。
这也意味着,我要控制我自己的滚动条。要做到这一点,我需要记住的第一个元素在屏幕上的元素数量。在每个滚动的事件,我需要在我的UserControl可见区域的重建项目。... ...更快的速度
UserControl的新版本几乎是我想要的东西它像。它是(几乎)快速,它可以滚动项目,即使项目不具有相同的高度。
但是如果我添加了很多的元素(比方说... 1000),它仍然得到一点点缓慢,闪烁可怕的。因此,下一步是添加"; updatequot;机制。我每次调用update(),增加一个成员更新,和每个EndUpdate()是下降。虽然更新是GT; 0,没有视觉上的东西就完成了。再次更新为0时,视觉上的东西就完成了。项目选择
现在我们有足够快的项目很多,我们可以添加/删除它们,它们可以滚动。但没有人会告知所选择的项目。
在我的脑海的第一件事是quot;让我们添加一个单击事件handlerquot。但是,这不是真的,因为如果子控件本身包含其他子控件,我们将永远不会被告知有关点击。因此,我们需要进行注册,以使所有儿童的单击处理程序递归控制(上删除注销)。因此,加入一个控制信息调用AttachClickEvents(ChildControl)。

private void AttachClickEvents( Control Control ) {

    Control.Click += new EventHandler( Control_Click );

    if( Control.Controls != null ) {

        foreach( Control C in Control.Controls ) {

            AttachClickEvents( C );

        }

    }

}

现在,如果任何子控件被点击,我们了解该事件。我们需要进行比较,如果点击控制在我们的控制清单。如果没有,我们需要采取家长控制和做比较,再次。如果我们发现在我们的名单控制,我们找到了控制,这就需要我们消防ControlSelected事件。排序项目
的最后一件事,是杰出的排序。这是很容易的。我们需要有一个可以从UserControl的外部设置的IComparer的公共财产。现在,如果比较器设置,添加/删除/从我们的项目清单的控制,需要items.Sort(比较器)的调用。使用代码
虽然我们有一个属性来控制我们的UserControl显示,我们可以不使用此列表来改变元素,因为Click事件处理程序设置不正确。他们只添加(管制),他们只是在删除(管制)或RemoveAt(指数)中删除。
公共方法和属性:{C}兴趣点
写这个控制显示了一些有趣的点,如单击事件或加快的背景部分解释,。1:方向扩展
现在,你可以设置在ListBox中的项目的方向。这意味着,如果你设置方向,以OrientationEnum.Vertical,你会得到自上而下(在您使用的项目比较)排序的项目清单。否则你会得到他们的顺序由左到右。
AdaptControlWidth属性如果设置为false,你会得到许多列(行),为适应控制(见截图)。扩展2:隐形
感谢我的读者,我是能够改变的行为时控制是无形的。一些滚动计算依赖于可见光范围内的控制项的数量。当无形的,这导致了quot;分工zeroquot;错误(更正)。感谢... ...
... {A},阅读文章,并给我一些提示,之前,我发表了... ...
如果你想获得良好的信息 - 读他的文章!历史2008-05-21:初始版本2008-06-25:增加取向和多COLS /行2008-06-29:更新文章

回答

评论会员:Xixles 时间:2011/12/16
例如,当该列表包含的项目,您可以使用Clear()方法清除虚拟列表,panelControls.Controls控制集合没有得到更新,使他们看到{。 BR}
编辑:如果你加入这一行开始重建(),它会解决的错误:

if (items.Count == 0) panelControls.Controls.Clear();


评论会员:游客 时间:2011/12/16
阿齐姆Bohmann首先,非常好,方便代码

我想使用的代码,但有一个滚动条的问题。

这是一个有点疯狂和神经质。
它更容易看到它,如果你使用数的UserControls,如2个或3个,。
另一件事,我使用一个TreeView的ListBox。 ListBox的往往是现实,但是,如果新的X数量控制列表中处于劣势的previoust,旧的控制x是取代旧其余均保持在ListBox。

我用Clear方法和重建,例如像

微软应该考虑使用这个例子中,作出新的ListBox版本。,

谢谢你这篇文章。
弗兰克

7月15日修改,2008下午07:05
评论会员:Thisisryan 时间:2011/12/16
嗨!弗兰克
感谢你在我的控制的兴趣。滚动条的问题,我也有我的程序。我将努力就可以了...

希望更多的控制遵循

关于
阿齐姆

读我的唇:没有更多的错误
评论会员:!cakirhal 时间:2011/12/16
此代码是优秀的,张贴的感谢。
我想知道如果一个滚动条的问题已经找到解决办法。
- 瑞安
评论会员:阿齐姆Bohmann 时间:2011/12/16
您好,
当我点击了附近的"开始"菜单的"显示桌面"图标,应用程序抛出"除以零"在运行时的错误。我评论这行代码:

"vScrollBar.Maximum = items.Count GT; 0(items.Count /栏) - 1:0;?"在ARBOScrollableListBox.cs文件

然后它工作正常。

这行代码的目的是什么
评论会员:?阿齐姆Bohmann 时间:2011/12/16
!喜那一抹感谢 - 这将在下一版本中固定...
这行代码,当点击滚动条内关于"大而全"的滚动距离的(如网页)

阿齐姆

读我的唇:没有更多的错误:
|