Silverlight:用Enter键替换Tab键切换焦点

业务系统中,很多录入人员习惯于用Enter键来代替Tab键切换控件焦点(虽然我个人并不觉得这样录入速度会变得有多高效,呵呵),有需求了,自然就得想办法满足。

思路:为了更灵活的控件焦点顺序,我决定用TabIndex来做文章,每个输入控件按下回车时,找到下一个比当前控件TabIndex更大且最接近的控件,然后focus().

XAML界面部分:

<UserControl x:Class="tab_key_test.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">



    <StackPanel x:Name="LayoutRoot" Background="White">

        <TextBox Margin="5" TabIndex="0"></TextBox>

        <CheckBox Margin="5" TabIndex="1" Content="CheckBox Test"></CheckBox>

        <TextBox Margin="5" TabIndex="2"></TextBox>

        <ComboBox Margin="5" TabIndex="3">

            <ComboBox.Items>

                <ComboBoxItem Content="ComboBox Test 11"></ComboBoxItem>

                <ComboBoxItem Content="ComboBox Test 22"></ComboBoxItem>

            </ComboBox.Items>

        </ComboBox>

        <TextBox Margin="5" TabIndex="4"></TextBox>

        <RadioButton Margin="5" Content="Radio Test" TabIndex="5"></RadioButton>

        <TextBox Margin="5" TabIndex="6"></TextBox>

    </StackPanel>

</UserControl>

  

CS后端代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;



namespace tab_key_test

{

    public partial class MainPage : UserControl

    {

        List<Control> allInputControls = new List<Control>();



        public MainPage()

        {

            InitializeComponent();



            this.Loaded += MainPage_Loaded;

        }



        void MainPage_Loaded(object sender, RoutedEventArgs e)

        {

            //把界面上的TextBox,RadioButton,ComboBox,CheckBox都加入列表

            //注:一般业务录入界面上只有这4种类型的输入控件,如果还有其实类型,可自行扩展

            allInputControls.AddRange(FindChildren<TextBox>(LayoutRoot).Cast<Control>());

            allInputControls.AddRange(FindChildren<RadioButton>(LayoutRoot).Cast<Control>());

            allInputControls.AddRange(FindChildren<ComboBox>(LayoutRoot).Cast<Control>());

            allInputControls.AddRange(FindChildren<CheckBox>(LayoutRoot).Cast<Control>());

            //按TabIndex排序

            allInputControls = allInputControls.OrderBy(c => c.TabIndex).ToList();

            foreach (Control c in allInputControls)

            {

                c.KeyDown += EnterKeyDownToTab;

                if (c is ComboBox)

                {

                    //ComboBox要特殊处理

                    (c as ComboBox).DropDownClosed += DropDownClosedToNext;

                }

            }

        }



        



        void EnterKeyDownToTab(object sender, KeyEventArgs e)

        {

            if (e.Key == Key.Enter)

            {

                GoToNextControl(sender);

            }

        }





        void GoToNextControl(object sender)

        {

            var self = sender as Control;

            if (self == null)

            {

                return;

            }



            var selfTabIndex = self.TabIndex;

            //找出下一个控件

            var nextControl = allInputControls.FirstOrDefault(c => c.TabIndex > selfTabIndex);

            if (nextControl != null)

            {

                nextControl.Focus();

            }

            else

            {

                allInputControls[0].Focus();//最后一个控件时,再跳到第一个(可选处理)

            }

        }





        /// <summary>

        /// 查找所有子元素(递归)

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <param name="parent"></param>

        /// <returns></returns>

        public static IEnumerable<T> FindChildren<T>(DependencyObject parent) where T : class

        {

            int count = VisualTreeHelper.GetChildrenCount(parent);

            if (count > 0)

            {

                for (int i = 0; i < count; i++)

                {

                    DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                    var t = child as T;

                    if (t != null)

                        yield return t;



                    IEnumerable<T> children = FindChildren<T>(child);

                    foreach (T item in children)

                        yield return item;

                }

            }

        }



        private void DropDownClosedToNext(object sender, EventArgs e)

        {

            GoToNextControl(sender);

        }

    }

}

 这个思路还可以应用到html网页上:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

	<head>

		<title>Enter Key Replace Tab</title>

		<script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.6/jquery.min.js"></script>

		<style type="text/css">

			input,select,textarea{

				padding:0;

				margin:5px;

				width:150px;

				display:block;

			}

		</style>

		

		<script type="text/javascript">			

		

			$(document).ready(function(){

				var inputs = $("input,textarea,select").sort(function(a,b){return a.tabIndex>b.tabIndex?1:-1});



				

				inputs.each(function(){

					$(this).keypress(function(e){

						if (e.keyCode==13||e.which==13){

							//修正textarea的多余回车问题(可选)

							//if ($(this).get(0).tagName == "TEXTAREA"){

							//	$(this).val($.trim($(this).val()));

							//};



							var selfTabIndex = parseInt($(this).attr("tabIndex"),10);

							var nextInput = null;



							//找出下一个元素

							for(var i=0; i<inputs.length; i++){

								if (inputs[i].tabIndex > selfTabIndex){

									nextInput = inputs[i];

									break;

								}

							}							



							if (nextInput != null){

								nextInput.focus();

							}

							else{

								inputs[0].focus();

							}

						}

					}).focus(function(){

						$(this).select();

					})

				})

			})

			

		</script>

	</head>

	<body>

		<input type="text" tabindex="0" value="000"/>

		<input type="text" tabindex="1" value="111"/>

		<textarea tabindex="2">222</textarea>

		<input type="radio" tabindex="3" id="r3" style="width:20px;display:inline"/><label for="r3">333</label>

		<input type="text" tabindex="4" value="444"/>

		<input type="checkbox" tabindex="5" id="c5" style="width:20px;display:inline"/><label for="c5">555</label>

		<input type="text" tabindex="6" value="666"/>

		<select tabindex="7">

			<option>777</option>

			<option>xxx</option>

		</select>

		<select size="2" tabindex="8">

			<option>888</option>

			<option>yyy</option>

		</select>

		

	</body>

</html>

  

 

你可能感兴趣的:(silverlight)