65.9K
CodeProject 正在变化。 阅读更多。
Home

PowerBuilder 的“陷阱”——带图片控件的网格数据窗口

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2012 年 6 月 28 日

CPOL

4分钟阅读

viewsIcon

26497

我正在开发一个应用程序中的“仪表板”风格的 datawindow,它显示网格数据和一些图形,以便用户可以轻松地查看更改/重要内容。使用网格 datawindow 有很多原因,特别是它们可以轻松地被用户更改

我正在开发一个应用程序中的“仪表板”风格的 datawindow,它显示网格数据和一些图形,以便用户可以轻松地查看更改/重要内容。使用网格 datawindow 有很多原因,特别是它们可以轻松地被用户根据自己的品味和偏好进行更改。由于用户可以调整各个列的大小,因此我无法在列上使用“显示为位图”选项来显示我的图形,因为它们可以调整大小,这会破坏 datawindow 上的图像。好吧,我会在单个图片上放置图片对象,然后使用表达式自动控制它们的位置。天哪,PowerBuilder 不是很棒吗?

现在,在我的特定情况下,我在一列上放置了一系列图片对象,列本身的值决定了哪个图片是可见的。这是通过图片对象的视觉属性上的表达式实现的标准操作。接下来要做的是根据图片所在的列设置图片对象的 X 位置;我希望图片的位置能够动态地随着用户拖动列到不同位置或改变其宽度而变化。到目前为止,一切都很好——我开始有点得意忘形了…

我启动了应用程序,然后“哇,哇,哇,哇,哇aaaa……”。

这是我启动应用程序时的样子。

看起来不错,我的可见性表达式是正确的。

我将“Mood”列调整得更宽,然后…

有些东西没有按预期工作。

好的,让我们尝试通过将 Name 拖到 Mood 之后来重新排列这些列。

这太糟糕了,grrrr……。

如果我把 Mood 列弄得更窄会怎样?

叹气。
好吧老板,这个什么时候截止?

首先,让我们处理定位问题。为了使图片上的表达式正常工作,每个图片都必须是唯一的。因此,这些表达式将不起作用

long(describe("custmood.X")) + 100
long(describe("custmood.X")) + 100
long(describe("custmood.X")) + 100

这是我的 datawindow 列上三个图片对象的 X 位置表达式。为了使它们唯一,我将它们更改为

long(describe("custmood.X")) + 100 // p_1.X
long(describe("custmood.X")) + 100 + 0 // p_2.X
long(describe("custmood.X")) + 100 * 1 // p_3.X

还要注意,“+ 100”与“+100”在此有所不同

现在当我运行应用程序,并且我更改了网格中列的顺序时,我得到了

将 Name 移到 Mood 之后。


凉爽

有一点需要注意。如果您打算使用 Modify 在运行时更改 X 位置表达式,而不是在 datawindow 定义中更改,那么每个“New”表达式都必须与原始表达式不同。感谢我的经理提供的这个技巧。

第二个问题有点棘手,是我在 PB 职业生涯中不同时期遇到过的问题。你可以在网上搜索答案,但要么找不到,要么找到很多不太好用的建议。很多时候,你不得不阻止用户调整列的大小,这消除了选择网格 datawindow 的主要原因之一。

由于我们处理的是我们在 datawindow 绘制器中创建的控件,当它们显示给用户时,大小是我们想要的,我们只需要捕获它们的宽度,然后在用户调整 datawindow 中的列大小时重新应用它们。但是,我们必须在 datawindow 上创建一个用户事件来完成此操作,因为当用户调整网格列大小时,没有标准事件会触发。

首先定义一个实例变量来保存 datawindow 上图片对象的 modify 信息。
接下来,在窗口打开后捕获图片对象的初始宽度值;“post open”风格的事件对此很有用。如果您的应用程序在运行时出于某种原因动态更改了这些值,您必须在更改后重置它,以便属性设置为正确的值。
在有问题的 datawindow 上定义一个用户事件,该事件将对图片对象执行 modify 操作。
定义一个映射到 pbm_dwnlbuttonup 的用户事件,该事件将发布第一个用户事件。当用户在 datawindow 上释放左鼠标按钮时(这发生在用户完成列大小调整时),将触发此事件。

//instance var and postopen event
type variables
string is_picture_widths
end variables

event we_postopen();// triggered from open of window
string ls_objects, ls_object, ls_type
long ll_col_pos, ll_col_start, ll_len
// load picture settings to instance variable
ls_objects = dw_1.Object.DataWindow.Objects
// go through tab separated list
ll_col_pos = pos(ls_objects, '~t')
ll_col_start = 1
ll_len = len(ls_objects)
DO WHILE ll_col_start < ll_len
	ls_object = mid(ls_objects, ll_col_start, ll_col_pos - ll_col_start)
	ls_type = dw_1.describe(ls_object + '.type')
	IF  ls_type = 'bitmap' then //only concerned about bitmaps (picture objects)
		is_picture_widths += ls_object + '.width = ' + dw_1.describe(ls_object + '.width') + '~r'
	END IF					
	ll_col_start = ll_col_pos + 1
	ll_col_pos = pos(ls_objects, '~t', ll_col_start)
	IF ll_col_pos = 0 then
		ll_col_pos = ll_len + 1
	END IF
LOOP
end event

event ue_lbuttonup;// call event to resize pictures if needed, mapped to PBM_DWNLBUTTONUP on datawindow
this.setredraw(FALSE)
this.event post ue_checkmodified()
end event

event ue_checkmodified();// posted from ue_lbuttonup
string ls_mess

IF this.object.datawindow.syntax.modified = "yes" THEN
	ls_mess = modify(is_picture_widths) // re apply the picture widths
	IF Len(ls_mess) > 0 THEN
		// error condition
	END IF
END IF
setredraw(true) //was set to false in calling event
end event

现在,当我们运行应用程序时,我们得到这个。

调整带有图片控件的列的大小

现在把它弄小一点。

啊,一切又恢复正常了。

我附加了一个示例应用程序 (PB12.5.1),演示了调整大小为何无效以及如何纠正。对象导出也包含在内,如果您需要创建自己的版本。运行示例时,请先在窗口打开后调整/重新定位列。这将显示图片对象的问题。当您单击“Modify Bitmap X Expressions”按钮时,图片对象 X 位置表达式的更改将显示在多行编辑控件中。

“Reset DWO”按钮会在您需要时重置 datawindow 对象。

© . All rights reserved.