如何人为控制Flex Tab键顺序 (DataGrid)

来源:互联网 发布:触摸屏多媒体软件开发 编辑:程序博客网 时间:2024/04/30 04:10
平常中更常见的是用Tab或者shift+Tab键。我们知道以前的桌面程序一般是指定控件的tabIndex就可以了。

在Felx中我们也可以这么做。我们知道每个Flex 控件基本都有2个属性tabIndex和tabEnabled.
默认情况下tabIndex == -1,
tabEnabled == false; 只有是Button或者TextField类型为’input’时,默认为true
因此我们可以给每个控件指定tabIndex,那么默认情况下我们不用添加多余事件代码就可以实现按照tabIndex从小到大的顺序,shift+tab是从大到小。但是碰到DataGrid和其他控件进行切换时会碰到一些很诡异的事情,按Tab时不是跳多了就是焦点不见了。问题主要是由于DataGrid自身就对Tab事件进行了特殊处理。

在实际应用过程中可能会更加复杂,有时候中间的某个控件可能是出于隐藏状态,这个时候的Tab顺序有可能因此而被打断,所以我们需要一些辅助的手段来处理Tab事件。

 

在这个例子中,上下分两块,上面一块的4个控件按Tab键是循环进行切换的,shift+tab也是一样,所以这个时候我们要对第一个和最后一个控件的keyDown事件进行特殊处理。

 

在下面部分,Tab键切换的顺序是First->Second->Third->Fouth->DataGrid->First->.....

这里还包括了对4个方向键的处理。

具体还是来看代码:

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    creationComplete="init()"
    tabEnabled="false">
 <mx:Script>
  <![CDATA[
   import mx.collections.XMLListCollection;
   private var xml:XML=<root><vo column1='A1' column2='B1' column3='C1' column4='D1'/>
     <vo column1='A2' column2='B2' column3='C2' column4='D2'/>
     <vo column1='A3' column2='B3' column3='C3' column4='D3'/></root>;
   [Bindable]
   private var dp:XMLListCollection=new XMLListCollection(xml.vo);
   [Bindable]
   private var text1:String="";
   [Bindable]
   private var text2:String="";
   //------------------------- section 1 ----------------------
   private function firstKeyDown(event:KeyboardEvent):void
   {
    try
    {
     //click tab
     if (event.keyCode == Keyboard.TAB && event.shiftKey)
     {
      end_1.setFocus();
      return;
     }
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_2.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_4.setFocus();
     }

    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }

   private function secondKeyDown(event:KeyboardEvent):void
   {
    try
    {
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_3.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_1.setFocus();
     }
    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }

   private function thirdKeyDown(event:KeyboardEvent):void
   {
    try
    {
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_4.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_2.setFocus();
     }

    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }

   private function fouthKeyDown(event:KeyboardEvent):void
   {
    try
    {
     //click tab

     if (event.keyCode == Keyboard.TAB && !event.shiftKey)
     {
      start_1.setFocus();
      return;
     }

     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_1.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_3.setFocus();
     }

    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }
   //~------------------------- section 1 end----------------------

   //------------------------- section 2 ------------------------

   private function keydown11(event:KeyboardEvent):void
   {
    try
    {
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_22.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP
      || (event.keyCode == Keyboard.TAB && event.shiftKey))
     {
      dataGrid.setFocus();
      dataGrid.editedItemPosition={columnIndex: dataGrid.columns.length - 1, rowIndex: dataGrid.dataProvider.length - 1};
     }
    }
    catch (e:Error)
    {
     trace(e.message);
    }
   }

   private function keydown12(event:KeyboardEvent):void
   {
    try
    {
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_23.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_21.setFocus();
     }
    }
    catch (e:Error)
    {
     trace(e.message);
    }
   }

   private function keydown13(event:KeyboardEvent):void
   {
    try
    {
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN)
     {
      comp_24.setFocus();
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_22.setFocus();
     }

    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }

   private function keydown14(event:KeyboardEvent):void
   {
    try
    {
     if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.DOWN
      || (event.keyCode == Keyboard.TAB && !event.shiftKey))
     {
      dataGrid.setFocus();
      dataGrid.editedItemPosition={columnIndex: 0, rowIndex: 0};
      return;
     }
     else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.UP)
     {
      comp_23.setFocus();
     }
    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }

   private function keydownDataGrid(event:KeyboardEvent):void
   {
    try
    {
     var v:Object=dataGrid.editedItemPosition;
     var ti:TextInput=TextInput(dataGrid.itemEditorInstance);
     //tab
     if (event.keyCode == Keyboard.TAB)
     {
      if (!event.shiftKey)
      {
       if (v != null && v.rowIndex == dataGrid.dataProvider.length - 1 && v.columnIndex == dataGrid.columns.length - 1)
       {
        start_2.setFocus();
       }
      }
      else
      {
       if (v != null && v.rowIndex == 0 && v.columnIndex == 0)
       {
        end_2_1.setFocus()
       }
      }
     }

     if (event.keyCode == Keyboard.DOWN)
     {
      if (v.rowIndex < dataGrid.dataProvider.length - 1)
      {
       v.rowIndex++;
       dataGrid.editedItemPosition=v;
      }
      else
      {
       comp_21.setFocus();
      }

     }
     else if (event.keyCode == Keyboard.RIGHT)
     {
      if (v.columnIndex < dataGrid.columns.length - 1)
      {
       v.columnIndex++;
       dataGrid.editedItemPosition=v;
      }
      else
      {
       comp_21.setFocus();
      }

     }
     else if (event.keyCode == Keyboard.UP)
     {
      if (v.rowIndex == 0)
      {
       comp_24.setFocus();
      }
      else
      {
       v.rowIndex--;
       dataGrid.editedItemPosition=v;
      }

     }
     else if (event.keyCode == Keyboard.LEFT)
     {
      if (v.columnIndex == 0)
      {
       comp_24.setFocus();
      }
      else
      {
       v.columnIndex--;
       dataGrid.editedItemPosition=v;
      }

     }

    }
    catch (e:Error)
    {
     trace(e.message);
    }

   }

   private function dataGridFocusIn(event:FocusEvent):void
   {
    try
    {
     var ti:TextInput=TextInput(dataGrid.itemEditorInstance);

     if (ti)
     {
      text2=ti.text;
     }

    }
    catch (e:Error)
    {
     trace(e.message);
    }
   }
  ]]>
 </mx:Script>

 <mx:Panel title="Tab键; Shift+Tab; 方向键切换界面元素例子"
     verticalGap="20"
     width="50%"
     height="50%"
     paddingTop="10"
     paddingLeft="10"
     paddingRight="10"
     paddingBottom="10">
  <mx:VBox width="100%"
     height="60"
     borderStyle="solid">
   <mx:HBox width="100%"
      height="20">
    <mx:Label text="Section One 循环切换:"
        fontSize="13"/>

    <mx:Spacer width="50"/>
    <mx:Label text="{text1}"
        fontSize="13"
        fontWeight="bold"
        color="0xC42B25"/>
   </mx:HBox>
   <mx:HBox width="100%"
      height="50%">
    <mx:Button id="start_1"
         width="1"
         height="1"
         label="a"
         tabEnabled="true"
         tabIndex="0"/>
    <mx:TextInput id="comp_1"
         text="First"
         tabEnabled="true"
         tabIndex="1"
         keyDown="firstKeyDown(event)"
         width="100"
         focusIn="{text1=comp_1.text}"/>
    <mx:Label text="->"/>
    <mx:Button id="comp_2"
         label="Second"
         tabEnabled="true"
         tabIndex="2"
         keyDown="secondKeyDown(event)"
         focusIn="{text1=comp_2.label}"/>
    <mx:Label text="->"/>
    <mx:Button id="comp_3"
         label="Third"
         tabEnabled="true"
         tabIndex="3"
         keyDown="thirdKeyDown(event)"
         focusIn="{text1=comp_3.label}"/>

    <mx:Label text="->"/>
    <mx:TextInput id="comp_4"
         text="Fouth"
         tabEnabled="true"
         tabIndex="4"
         keyDown="fouthKeyDown(event)"
         width="100"
         focusIn="{text1=comp_4.text}"/>

    <mx:Button id="end_1"
         width="1"
         height="1"
         label="b"
         tabEnabled="true"
         tabIndex="5"/>

   </mx:HBox>
  </mx:VBox>

  <mx:VBox width="100%"
     height="100%"
     borderStyle="solid">

   <mx:HBox width="100%"
      height="20">

    <mx:Label text="Section Two 循环切换:"
        fontSize="13"/>

    <mx:Spacer width="50"/>

    <mx:Label text="{text2}"
        fontSize="13"
        fontWeight="bold"
        color="0x21911D"/>
   </mx:HBox>

   <mx:HBox width="100%"
      height="40">
    <mx:Button id="start_2"
         width="1"
         height="1"
         label="a"
         tabEnabled="true"
         tabIndex="10"/>
    <mx:TextInput id="comp_21"
         text="First"
         tabEnabled="true"
         tabIndex="11"
         keyDown="keydown11(event)"
         width="100"
         focusIn="{text2=comp_21.text}"/>
    <mx:Label text="->"/>
    <mx:Button id="comp_22"
         label="Second"
         tabEnabled="true"
         tabIndex="12"
         keyDown="keydown12(event)"
         focusIn="{text2=comp_22.label}"/>
    <mx:Label text="->"/>
    <mx:Button id="comp_23"
         label="Third"
         tabEnabled="true"
         tabIndex="13"
         keyDown="keydown13(event)"
         focusIn="{text2=comp_23.label}"/>
    <mx:Label text="->"/>
    <mx:TextInput id="comp_24"
         text="Fouth"
         tabEnabled="true"
         tabIndex="14"
         keyDown="keydown14(event)"
         width="100"
         focusIn="{text2=comp_24.text}"/>
    <mx:Button id="end_2_1"
         width="1"
         height="1"
         label="b"
         tabEnabled="true"
         tabIndex="15"/>
   </mx:HBox>

   <mx:DataGrid id="dataGrid"
       keyDown="keydownDataGrid(event)"
       tabEnabled="true"
       tabIndex="16"
       focusIn="dataGridFocusIn(event)"
       dataProvider="{dp}"
       editable="true">
    <mx:columns>
     <mx:DataGridColumn dataField="@column1"
            width="100"
            editable="true"
            headerText="Col1"/>
     <mx:DataGridColumn dataField="@column2"
            headerText="Col2"
            width="180"
            editable="true"
            textAlign="right"/>
     <mx:DataGridColumn dataField="@column3"
            headerText="Col3"
            width="110"
            editable="true"
            textAlign="right"/>
     <mx:DataGridColumn dataField="@column4"
            headerText="Col4"
            width="110"
            editable="true"
            textAlign="right"/>
    </mx:columns>
   </mx:DataGrid>

   <mx:Button id="end_2_2"
        width="1"
        height="1"
        label="b"
        tabEnabled="true"
        tabIndex="17"/>
  </mx:VBox>
  <mx:Text text="非循环切换比较简单,对于第一个和最后一个界面元素不需要进行特殊处理,这里就省略Demo"
     fontSize="12"/>
 </mx:Panel>
</mx:Application>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0 0