问题标签 [tdbgrid]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
1302 浏览

delphi - TDBGrid onSelect

我想自定义 TDBGrid:

1) 添加 onSelect/onUnselect 事件 - 例如有利于显示所选项目的数量。

2)在鼠标左键单击时删除选择项。我继承了 TDBGrid 并重写了 MouseDown,但是无法移动或调整列的大小:(

那么,该怎么做呢?

D2009

0 投票
3 回答
15914 浏览

delphi - 在 Delphi 的 TDBGrid 中查找当前行

有没有办法找出 TDBGrid 中的哪一行是当前行?

0 投票
3 回答
4517 浏览

delphi - 如何在 Delphi 5 中从 TDBGrid 中获取选定的单元格

我在表单上有一个 DBGrid 并且我进行了多项选择,我现在需要将选定的单元格(它们是电子邮件地址)发送到 Outlook 的“TO Box”我该怎么做,我将不胜感激(Delphi5)提前致谢

0 投票
4 回答
4599 浏览

delphi - 打印 TDBGrid

我正在使用 Delphi 2009,我真的需要创建一个可以在 DBGrid 中打印所有数据的按钮。我很感激我能得到的所有帮助。

0 投票
2 回答
1852 浏览

lazarus - free pascal, tdbgrid, 获取当前行

我是免费的 pascal 和 lazarus 的新手,我想知道如何从 tbgrid 中的选定行获取行数据(例如 id 列)?

0 投票
2 回答
4980 浏览

delphi - 恢复 TDBGrid 中的水平滚动位置

我写了一个简单的方法来对 TD​​BGrid 中的列进行排序。如果 Option.RowSelect 设置为 False 一切正常,但如果 R​​owSelect 为 True 则水平位置滚动不会在排序列后恢复。所以我尝试 GetScrollPos 和 SetScrollPos 来恢复水平滚动位置,滚动条到正确的位置但 TDBGrid 没有滚动,这里是方法:

这可以在循环中使用 Perform(WM_HSCROLL, SB_LINERIGHT, 0) 修复,但这不是一个好主意。有人有更好的解决方案吗?

0 投票
3 回答
6193 浏览

delphi - 在 DBGrid 中移动列似乎会移动附加的数据集字段

上周我观察到了一些我没有预料到的事情,将在下面描述。我很好奇为什么会发生这种情况。它是 TDataSet 类内部的东西、TDBGrid 的工件还是其他东西?

打开的 ClientDataSet 中的字段顺序发生了变化。具体来说,我在使用 FieldDefs 定义其结构后,通过调用 CreateDatatSet 在代码中创建了一个 ClientDataSet。此 ClientDataSet 结构中的第一个字段是名为 StartOfWeek 的日期字段。不久之后,我也编写的代码(假设 StartOfWeek 字段位于第零位 ClientDataSet.Fields[0])失败了,因为 StartOfWeek 字段不再是 ClientDataSet 中的第一个字段。

经过一番调查,我了解到 ClientDataSet 中的每个字段都可能在特定时刻出现在与创建 ClientDataSet 时的原始结构不同的某个位置。我不知道这可能会发生,在谷歌上搜索也没有提到这种效果。

发生的事情不是魔术。这些字段本身并没有改变位置,也没有根据我在代码中所做的任何事情而改变。导致字段在 ClientDataSet 中物理出现位置变化的原因是用户更改了 ClientDataSet 附加到的 DbGrid 中列的顺序(当然是通过 DataSource 组件)。我在 Delphi 7、Delphi 2007 和 Delphi 2010 中复制了这种效果。

我创建了一个非常简单的 Delphi 应用程序来演示这种效果。它由一个带有一个 DBGrid、一个 DataSource、两个 ClientDataSet 和两个 Button 的表单组成。此表单的 OnCreate 事件处理程序如下所示

Button1(标记为 Show ClientDataSet Structure)包含以下 OnClick 事件处理程序。

要演示移动场效果,请运行此应用程序并单击标有 Show ClientDataSet Structure 的按钮。您应该会看到类似此处所示的内容:

接下来,拖动 DBGrid 的列来重新排列字段的显示顺序。再次单击 Show ClientDataSet Structure 按钮。这次您将看到与此处显示的内容类似的内容:

此示例的显着之处在于 DBGrid 的列正在移动,但对 ClientDataSet 中 Fields 的位置有明显影响,因此 ClientDataSet.Field[0] 中的字段位置为 1点不一定在片刻之后。而且,不幸的是,这显然不是 ClientDataSet 问题。我对基于 BDE 的 TTables 和基于 ADO 的 AdoTables 进行了相同的测试,得到了相同的效果。

如果您从不需要引用在 DBGrid 中显示的 ClientDataSet 中的字段,那么您不必担心这种影响。对于你们其他人,我可以想到几个解决方案。

避免此问题的最简单但不必要的优选方法是防止用户重新排序 DBGrid 中的字段。这可以通过从 DBGrid 的 Options 属性中删除 dgResizeColumn 标志来完成。虽然这种方法是有效的,但从用户的角度来看,它消除了潜在的有价值的显示选项。此外,删除此标志不仅会限制列重新排序,还会阻止调整列大小。(要了解如何在不删除列调整大小选项的情况下限制列重新排序,请参阅http://delphi.about.com/od/adptips2005/a/bltip0105_2.htm。)

第二种解决方法是避免根据字面位置引用数据集的字段(因为这是问题的本质)。换句话说,如果您需要引用 Count 字段,请不要使用 DataSet.Fields[2]。只要您知道字段的名称,就可以使用 DataSet.FieldByName('Count') 之类的名称。

然而,使用 FieldByName 有一个相当大的缺点。具体来说,此方法通过遍历 DataSet 的 Fields 属性来识别字段,并根据字段名称查找匹配项。由于每次调用 FieldByName 时都会执行此操作,因此在需要多次引用字段的情况下(例如在导航大型 DataSet 的循环中)应避免使用此方法。

如果您确实需要重复(并且多次)引用该字段,请考虑使用类似于以下代码片段的内容:

还有第三种解决方案,但这仅在您的 DataSet 是 ClientDataSet 时可用,就像我原来的示例中的那个一样。在这些情况下,您可以创建原始 ClientDataSet 的克隆,它将具有原始结构。因此,无论用户对显示 ClientDataSets 数据的 DBGrid 做了什么,在第零位置创建的任何字段仍将位于该位置。

这在以下代码中进行了演示,该代码与标记为 Show Cloned ClientDataSet Structure 的按钮的 OnClick 事件处理程序相关联。

如果您运行此项目并单击标有“显示克隆的 ClientDataSet 结构”的按钮,您将始终获得 ClientDataSet 的真实结构,如下所示

附录:

需要注意的是,基础数据的实际结构不受影响。具体来说,如果在更改 DBGrid 中列的顺序后,调用 ClientDataSet 的 SaveToFile 方法,则保存的结构是原始(真正的内部)结构。此外,如果将一个 ClientDataSet 的 Data 属性复制到另一个,则目标 ClientDataSet 也会显示真实的结构(这类似于克隆源 ClientDataSet 时观察到的效果)。

同样,对绑定到其他测试数据集(包括 TTable 和 AdoTable)的 DBGrid 的列顺序的更改实际上不会影响基础表的结构。例如,显示来自 Delphi 附带的 customer.db 示例 Paradox 表的数据的 TTable 实际上并没有改变该表的结构(您也不希望它改变)。

我们可以从这些观察中得出结论,DataSet 本身的内部结构保持不变。因此,我必须假设在某处存在 DataSet 结构的二级表示。而且,它必须与 DataSet 相关联(这似乎有点过头了,因为并非所有使用 DataSet 都需要这个),与 DBGrid 相关联(这更有意义,因为 DBGrid 正在使用此功能,但不是由 TField 重新排序似乎与 DataSet 本身持​​续存在的观察结果支持),或者是其他东西。

另一种选择是效果与 TGridDataLink 相关联,TGridDataLink 是为多行感知控件(如 DBGrids)提供数据感知的类。但是,我也倾向于拒绝这种解释,因为这个类与网格相关联,而不是与 DataSet 相关联,因为效果似乎与 DataSet 类本身有关。

这让我回到了最初的问题。这种效果是 TDataSet 类内部的东西、TDBGrid 的工件还是其他东西?

请允许我在这里强调一些我添加到以下评论之一的内容。最重要的是,我的帖子旨在让开发人员意识到,当他们使用可以更改列顺序的 DBGrid 时,他们的 TField 的顺序也可能会发生变化。该工件可能会引入难以识别和修复的间歇性和严重错误。而且,不,我不认为这是一个 Delphi 错误。我怀疑一切都按照设计的方式工作。只是我们中的许多人都不知道这种行为正在发生。现在我们知道了。

0 投票
5 回答
6553 浏览

delphi - 如何使 TDBGrid 的列适合网格的宽度?

我有一个带有预定义列的 TDBGrid,但我无法获得正确的宽度。我可以在表单设计器中弄乱列的 Width 属性,并在设计时使宽度看起来恰到好处,但在运行时,无论出于何种原因,列往往会明显更宽,最后我会得到一个滚动条在网格的底部。有没有办法让列的大小正确,而不需要所有的反复试验,特别是如果网格只有一两个?

0 投票
2 回答
6350 浏览

delphi - Delphi 中的只读 TDBGrid/TwwDBGrid 单元格?

是否可以在 Delphi 中设置 TDBGrid(或 TwwDBGrid)单元格只读?目前,我正在摆弄从字面上使单元格变灰并在编辑后将其清除,但这并不是很令人满意。

干杯,杰米

0 投票
1 回答
4061 浏览

delphi - Delphi - 使用 DBGrid 从搜索中选择行

我已经使用查询搜索了数据库。

搜索结果显示在 DBGrid 组件中,供用户选择他/她希望继续处理的行。

DBGrid 始终将记录指针设置为结果集中的第一条记录,因此默认情况下始终“选中”一行。我需要将此行为更改为在首次显示数据时不选择任何行,以便我可以确定用户是否实际进行了选择。

是否可以判断是否没有进行选择,即用户没有选择任何行?

非常欢迎任何帮助!