登录注册
上海交通大学论坛 > 数据库 > 浏览当前帖子 手机版 关闭左侧栏
编写行选择函数
返回本版】  【发表帖子】  【回复帖子 浏览量  8851      回帖数 0
新手的手    等级  

楼主 发表于  2012/5/20 2:52:26    编 辑   


 
我们介绍了使用自定义用户对象取代系统自身的数据窗口的技术,采 
用这种办法我们可以把对数据窗口经常做的操作编写成为对象函数, 
在数据窗口的祖先对象中进行定义,并将其封装起来,而不必在每一个 
使用数据窗口的窗口之中重复编程。在数据窗口中我们经常要使用对 
各条记录的选择操作,本期我们介绍如何将这一功能在对象函数中实 
现,以拓展数据窗口的基本功能。 

    进行选择的不同方法 
    我们在数据窗口中需要进行行选择操作,如用户为了修改数据或 
看到更详细的内容而选择了某一行;在另一些情况下,用户可能要同时 
删除或修改多行,这时,我们需要有使用户在一个数据窗口中同时选择 
多行的功能。这在PowerBuilder中是相当容易做到的,但是,如果在一 
个数据窗口祖先中没有标准的函数来处理这些,而在每个窗口中重复 
编程,就非常麻烦。 
    我们首先来看一看进行行选择的不同方法。 
    .所有行都不加亮通常情况下数据窗口不加亮任何行。这对于那 
些只允许用户进行滚动和查看的数据列表或那些单行的数据窗口是合 
适的。 
    .单行选择单行选择意味着用户在同一时间只能选择一行来执行 
一些动作,如删除或在主从关系的列表中显示详细信息,这是非常有用 
的。下面是实现单行选择功能的代码
    EventRowFocusChangedif GetRow() > 0 then 
      SelectRow( 0, FALSE ) 
      SelectRow( GetRow(), TRUE )end if. 
      多行的自动选择多行的自动选择表现为:当用户点击一个未加 
亮的行时,该行将变亮; 反之,用户点击一个加亮行,该行将不加亮。 
为了实现上述功能,在RowFocusChanged事件中加入如下代码
    Event:RowFocusChangedObjectAny DataWindowif GetRow() > 
 0 then 
      if IsSelected( GetRow() ) then 
        SelectRow( GetRow(), FALSE ) 
      else 
        SelectRow( GetRow(), TRUE ) 
      end if 
    end if 
    或者简化成为下面的一行代码
    if GetRow() > 0 then SelectRow( GetRow(), NOT IsSelected 
( GetRow())) 
    .shift、control或control+shift+鼠标的使用 
    Windows的文件管理器或其它Windows程序中,您可以使用Shift、 
Control或Control+Shi ft这种键盘与鼠标的组合来选择。PowerBuil 
der在数据窗口中没有提供这样的能力,我们必须自己实现。 
    我们应当实现的组合功能是
图1 
    要建立这样的功能,数据窗口必须记录当前的起始行。我们声明 
这样一个实例变量
    protected   long  il_ anchor _ row 
    当用户点击鼠标或进行了键盘操作时,我们要测试用户是否同时 
按下了Shift或Control 键,方法是用KeyDown()函数,检查有没有KeyS 
hift!和KeyControl!,如有这样的键按下则记录起始行。 

    编写行选择函数 
    为了在用户点击鼠标或进行键盘操作时使上述行为发生作用,我 
们必须在Clicked事件和一个映射到Pbm _ dwnkey事件的自定义用户 
事件中调用我们自己的行选择函数。这样,不管用户是点击鼠标还是 
击中键盘,选择行为都会发生。我们也可以将这个功能放入RowFocusC 
h anged事件中。 
    为了使这个行选择功能可重用,这里我们建立两个函数。一个函 
数设置我们希望的选择行为类型,另外一个真正执行该选择行为。首 
先我们使用一个实例变量来设定选择行为的值 
    protected integer   ii _ select_ behavior 
    这个变量中将存放下面的一些值。 
图2 
    如果使用的是保护变量或私有变量,这就意味着本对象以外的程 
序无法访问,因此必须为□□程序员建立对这些变量赋值和获取这些 
变量值的函数。 
    另外,还需要一些函数来执行基于该变量的过程。 
    函数:uf_SetSelect(Select_behavior)我们要写的第一个函数将 
允许程序员设置选择行为。 
     函数public integer uf_ SetSelect( integer ai_ select_ 
 behavior)/* 本函数设置数据窗口的选择行为值 
     下列为有效的选择行为值 
    */CHOOSE CASE ai_select_behavior  CASE 0, 1, 2, 3, 99 
     ii_ select_ behavior = ai_ select_ behavior 
     // 至少一行将被选中 
     if ai_ select_ behavior = 1 then 
       uf_ process_ select( GetRow(), "Keyboard" ) 
     end if 
     if ai_ select_ behavior = 99 then 
       SetRowFocusIndicator(Hand!) 
     else 
       SetRowFocusIndicator(OFF!) 
     end if 
     return 0   CASE ELSE 
     return -1 
    END CHOOSE 
    一旦选择类型被设置,所有的行都必须被处理。我们把这部分代 
码放入一个叫作uf_ Pr ocessSelect的函数中。这个函数处理选择行 
为。我们需要告诉该函数要处理的行和该请求是通过鼠标还是键盘发 
出的。下面是该函数代码
    函数:uf_ ProcessSelect(long al_ row, string as_ input_ t 
ype) 
    long    l_ row 
    boolean b_ reset_ anchor 
    boolean b_ keyboard, b_ mouse 
    //  鼠标动作还是键盘动作? 
    if Upper(left(as_input_type,1)) = "K" then 
      b_ keyboard = TRUEelse 
      b_ mouse = TRUEend if 
      /*  确认鼠标点在了数据窗口的记录上*/ 
      if al_ row < 1 Then Return -1 
      /*  是否要确定起始行 */ 
      b_ reset_ anchor = TRUE 
      SetRedraw(FALSE) 
      CHOOSE CASE ii_ select_ behavior 
      CASE 0, 99        //  无 
      CASE 1            //  单行选中 
      SelectRow(0,FALSE) 
      SelectRow(al_row,TRUE) 
      CASE 2            // 多行选中 
      if b_ mouse then 
      SelectRow(al_ row, NOT IsSelected( al_ row )) 
      end if 
      CASE 3 
        if keyDown(KeyShift!) and KeyDown(KeyControl!) then 
          if il_anchor_row > al_row then 
            FOR l_ row = il_ anchor_ row TO al_ row STEP -1 
              this.selectrow(l_row,TRUE) 
            NEXT 
          else 
            FOR l_ row = il_ anchor_ row TO al_ row 
              this.selectrow(l_row,TRUE) 
            NEXT 
          end if 
        else if KeyDown(KeyShift!) then 
          SelectRow(0,FALSE) 
          IF il_ anchor_ row > al_ row then 
            FOR l_ row = il_ anchor_ row TO al_ row STEP -1 
              this.selectrow(l_ row,TRUE) 
            NEXT 
          else 
            FOR l_ row = il_ anchor_ row TO al_ row 
              this.selectrow(l_row,TRUE) 
            NEXT 
          end if 
          b_ reset_ anchor = FALSE 
        elseif Keydown(KeyControl!) then 
          SelectRow( al_row, NOT IsSelected( al_row ) )   el 
se 
          SelectRow(0,FALSE) 
        SelectRow(al_ row,TRUE) 
        end if 
        END CHOOSE 
        SetRedraw(TRUE) 
        if b_ reset_ anchor then il_ anchor_ Row = al_ row 
        return 0 
        现在,要执行行选择时,只需调用uf_ProcessSelect()函数。 
        一般当用户在一个数据窗口中点击了鼠标或是按下了上、下 
箭头键时,调用这个函数。另外还有捕获home和end键的代码。下面是 
we_keydown用户事件映射到Pbm_dwnkey事件中的代码
    Eventwe_ keydown (pbm_dwnkey) 
    ObjectAny DataWindow 
    if KeyDown(KeyDownArrow!) and GetRow() <> RowCount() the 

      uf_ processSelect( GetRow() + 1 , "Keyboard") 
    elseif KeyDown(KeyUpArrow!) and GetRow() <> 1 then 
      uf_ processSelect( GetRow() - 1 , "Keyboard") 
    elseif KeyDown(KeyHome!) and RowCount() > 0 then 
      uf_ processSelect( 1, "KeyBoard") 
    elseif KeyDown(KeyEnd!) and RowCount() > 0 then 
      uf_ processSelect( RowCount(), "Keyboard") 
    end if 
    最后,我们需要在clicked事件中加入
     uf_ processSelect(GetClickedRow(), "Mouse") 
     在这个祖先函数中编写这样一个行选择的函数只是作为一个简 
单的实例,相信读者一定能因此受到启发,编写出更多的函数,以拓展 
数据窗口的基本功能 
1
表情
所有内容均为会员自愿发表,并不代表本站立场.
论坛帮助 会员认证删帖申请 联系我们