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

使用 Tag 属性 - 第三部分

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2012年1月19日

CPOL

7分钟阅读

viewsIcon

14855

downloadIcon

60

DataWindow 列的 Tag 属性的使用

这是本系列文章的第三部分,也是最后一部分,介绍了一种用于 DataWindow 列的 Tag 属性的提案。我最初的想法是提供一种为每列自动设置微帮助的方法。当然,如果您使用 MDI 应用程序,则有一个设置微帮助的函数,但该函数仅在 MDI 中可用。如果您使用任何其他应用程序类型,则无法使用此功能。

即使您确实有一个 MDI,我也发现微帮助不像我希望的那样有用。微帮助总是在框架上,离列很远。用户可能会完全错过它。

为了实现一些可能更有用的功能,我们在工具库中创建了几个对象,它们组合在一起将提供我们所需的功能。您需要这些对象才能重现我们在此处所做的操作。如果您没有从之前的文章中获得它们,您仍然可以在本文的下载源代码中找到它们。

首先,我们必须考虑我们想做什么。我喜欢做的最常见的事情之一是将“pre”(前)和“post”(后)事件关联到 DataWindow 列。我们可以进行设置,以便在列获得焦点之前有一个事件,类似于 PFC 中窗口的 preOpen 和 postOpen 事件。为此,我们需要能够在 Tag 属性中有两个不同的值。一个用于命名 pre-event,另一个用于 post-event。

当然,首先要决定隐喻。我们如何区分 pre-event 和 post-event?我们有一个 Tag,它是一个字符串。我们如何分隔值?

一方面,我们可以使用 ini 文件隐喻,key=value。我们仍然会面临多个值的问题。我们可以这样做

Pre-event=ue_pre_focus;post-event=ue_post_focus

我更喜欢另一种我从某处学到的风格

[pre_event]ue_pre_focus[post_event]ue_post_focus

当列获得焦点时,我们需要扩展我们的 DataWindow 对象,将所有键/值对加载到我们的 key_value 对对象中。

从一个 DataWindow 开始

我们需要的第一件事是一个 DataWindow,它能给我们一些合理的使用对象。我们来做一个员工编辑器 DataWindow。

创建一个具有 freeform 演示风格的新 DataWindow。它需要一个 SQL Select 数据源。选择所有列,然后按姓氏和名字排序。

当然,DataWindow 需要进行格式化。它看起来一点也不好。emp_id 应该是只读的,所以我们将其制作成一个计算字段。

我们需要为部门和经理字段创建下拉列表。它们是 ID,但如果我们制作一个下拉列表 DataWindow,它们可以显示名称。所以我们需要两个新的 DataWindow。我喜欢将它们命名为 dddw_department 和 dddw_employee,因为我可能想在其他地方重用它们。将它们放在自己的 pbl 中是个好主意,这样您就可以始终快速找到它们。我将它们放在我的 tools pbl 中。

两个下拉列表都将是只读的,所以我们删除所有列并添加一个计算字段。员工下拉列表的计算字段具有此表达式

‘(‘ +  emp_id + ‘) ‘ +  emp_lname + ‘, ‘ +  emp_fname

部门的下拉列表 DataWindow 稍微复杂一些,但也不是太难。您需要从部门表中选择部门名称。在部门表中,您会找到一个名为 dept_head_id 的列。使用它连接到员工表并获取部门负责人的姓名(参见图 1)。

图 1

请注意,如果您首先选择部门表,然后选择员工表,您的连接将基于 dept_id。您需要更改它。如果您先打开员工表,那么连接将是您想要的。

最后按部门名称排序。然后删除 DataWindow painter 上的所有对象并添加一个计算字段。这是我的表达式

department_dept_name + ‘ (‘ +  employee_emp_lname + ‘, ‘ +  employee_emp_fname + ‘)'

格式化 DataWindow 后,我们将其放入窗口并检索它。当然,该窗口需要从我们的应用程序打开事件中打开。

我们在 DataWindow 下方添加一个静态文本。我们将用于测试。您的窗口应该看起来像图 2。

图 2

终于到了文章的重点

我们真正需要的是一个行为类似于 rowFocusChanging 事件但针对列的事件。我们来创建它。我们需要将正在离开的列和将要进入的列传递给该事件。我们在 u_dw 中完成此操作,并首先添加一个实例变量来保存我们之前所在的列。完成后,这些将是我们的实例变量

U_dw instance variables
private string is_selection_mode = "n"
private n_cst_dw_row_helper idw_row_helper
private u_dw_microhelp io_microhelp
private boolean ib_microhelp_registered = FALSE
private string is_last_column = ""
n_cst_key_value_collection io_key_values

注意:最后一个变量将在本文后面使用。请耐心等待。

我们将使用 is_last_column 来存储我们之前所在的列。正如您所见,它被初始化为空字符串。接下来,我们需要创建一个 itemFocusChanging 事件,就像 rowFocusChanging 一样。它不需要任何代码。它只需要存在并接受两个字符串变量。以下是它的代码

U_dw. itemFocusChanging
// ARGUMENTS
// string as_old_column
// string as_new_column
// DESCRIPTION
// As_old_column is the column we are coming
// from. as_new_column is the column we are going to

现在我们需要从 ItemFocusChanged 事件中调用这个列。这是代码

u_dw.ItemFocusChanged
// ARGUMENTS Long row, dwo the column
// DESCRIPTION
// If there is a tag property set for the dwo and if the microhelp is instantiated
// I display that tag
// Then we need to call the new itemFocusChanging events passing
// the old column and the new one.
// 3/26/2011 Rik Brooks
// 5/20/2011 Rik Brooks - added the call to the itemFocusChanging
IF ib_microhelp_registered then io_microhelp.text = dwo.tag
trigger event itemFocuschanging( is_last_column, dwo.name)
is_last_column = dwo.name

所以现在我们有了一个事件,它允许我们处理离开列和进入列。这正是我们所需要的。

自动化我们的事件

下一步是向我们的新事件添加代码,该代码会检查两个列中的 Tag。如果旧列中有“post”事件 Tag,则先执行它。然后我们检查新列中是否有 pre-event Tag 并执行它。

此事件有一个小转折。我们不知道 Tag 中可能有多少个命令。可能只有一个,或者两者都有,或者将来我们可能有许多。这时我们需要 key / value 对象。查看 tools pbl,您会找到 n_cst_key_value_collection。同样,如果您没有 tools.pbl,您可以下载它,或者给我发邮件,我会发给您。

这个对象只有两个函数与我们相关。我们将需要 of_addof_value。我们从 itemFocusChanging 事件调用 of_add。

当我考虑要做什么时,我意识到我们在创建 key value 对象时错过了一个至关重要的函数。我忘记添加一个函数来清除该对象以便可以重用它。我们来打开该对象并添加 of_clear 函数

n_cst_key_value_collection.of_clear
// DESCRIPTION
// resets the object so that it holds no values
ids_key_value.reset( )

这是我们使用之前提到的神秘实例变量 lo_key_values 的地方。它将保存当前对象的 Tag 中的值。首先,我们必须创建它。我们在 u_dw 的构造函数中执行此操作

Constructor of u_dw
// DESCRIPTION - initialize variables
io_key_values = create n_cst_key_value_collection

现在在 itemFocusChanging 中,我们添加使这一切正常工作的代码。

U_dw. itemFocusChanging
// string as_old_column
// string as_new_column
// DESCRIPTION
// As_old_column is the column we are coming
// from. as_new_column is the column we are going to.
// It also handles pre and post events for the column
if io_key_values.of_count() > 0 then
// We have values on the tag of the old column
string ls_event, ls_tag
ls_event = io_key_values.of_value( "post_event")
if len(ls_event) > 0 then triggerevent(ls_event)
end if
// Post event is done. Now we clear out the key values
// and load it with the new column.
io_key_values.of_clear()
ls_tag = this.describe(as_new_column + ".Tag")
if len(ls_tag) > 0 then
// We have a tag, load it into our key value object
// Format is [key]value
int li_left, li_right, li_next_left
string ls_key, ls_value
li_left = pos(ls_tag, "[") // the first left bracket
do while li_left > 0
li_right = pos(ls_tag, "]", li_left)
if li_right > 0 then
ls_key = mid(ls_tag, li_left + 1, li_right - li_left - 1)
li_next_left = pos(ls_tag, "[", li_right)// Now find the next key
if li_next_left > 0 then
ls_value = mid(ls_tag, li_right + 1, li_next_left - li_right - 1)
else
ls_value = right(ls_tag, len(ls_tag) - li_right)
end if
// Finally we can add to our key values
io_key_values.of_add(ls_key, ls_value)
li_left = li_next_left
else
// If there is no right bracket then we are done, something
// somehow got corrupted. Just forget the whole
// thing
li_left = -1
end if
loop
end if
// Done. Now let's see if there is a pre event for the new one
ls_event = io_key_values.of_value( "pre_event")
if len(ls_event) > 0 then triggerevent(ls_event)

几乎完成 基本上我们已经完成了,但我们需要一个测试。回到您的 d_employee DataWindow。转到 emp_fname 列,并在 Tag 中输入

[pre_event]ue_pre[post_event]ue_post

最后打开 w_main。为 dw_1 添加两个新事件。一个命名为 ue_pre,另一个命名为 ue_post。在每个事件中放置一个消息框。现在运行您的应用程序。当您进入名字字段时,ue_pre 事件将触发。当您离开该列时,ue_post 事件将触发。

显然,您可以拥有任意数量的事件。您可以拥有 ue_pre_nameue_prev_city 等。您还可以做得更远。您可以添加其他类型的 Tag 命令。所有命令都将自动进入 key value 对象。您只需在 itemFocusChanging 事件中为它们添加功能。

哦,对了,这让我想起了一件事——我敢打赌,您会发现 itemFocusChanging 事件除了 Tag 值之外还有很多用途。

© . All rights reserved.