Silverlight 中回车键代替 Tab键的类

来源:转载

在Silverlight中,处理回车键代替 Tab比较麻烦,现在本人写了一个类,简单调用就可实现,原理是先扫描父控件下的所有控件,然后设置每个控件的 keyUp事件,最后根据设置的 TabIndex排序。调用示例代码为:

    public partial class TestPage : Page    {
        public TestPage()
        {
            InitializeComponent();
            base.Loaded += new RoutedEventHandler(TestPage_Loaded);
        }

        void TestPage_Loaded(object sender, RoutedEventArgs e)
        {
            // 设置 回车代 Tab
            new EnterToTab(this);
        }
    }

 

EnterToTab.cs代码如下:

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Threading;
namespace Ktwl.Common.Controls
{
    public class EnterToTab
    {
        private static List<Type> _ctrlTypes = new List<Type>()
        {
            typeof(DatePicker),
            typeof(TextBox),
            typeof(PasswordBox),
            typeof(CheckBox),
            typeof(ComboBox),
        };
        public static void RegisterType(Type type)
        {
            if (!_ctrlTypes.Contains(type))
            {
                _ctrlTypes.Add(type);
            }
        }
        public static IEnumerable<T> FindChildren<T>(DependencyObject parent) where T : class
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);
            if (count > 0)
            {
                for (var i = 0; i < count; i++)
                {
                    var child = VisualTreeHelper.GetChild(parent, i);
                    var t = child as T;
                    if (t != null)
                        yield return t;
                    var children = FindChildren<T>(child);
                    foreach (var item in children)
                        yield return item;
                }
            }
        }
        private UIElement _parent;
        private List<Control> _controls = new List<Control>();
        public EnterToTab(UIElement parent)
        {
            _parent = parent;
            // 如果控件还没有加载完就调用 Associate() 方法,则不能查找到子控件,
            // 所以用定时器
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromTicks(100);
            timer.Tick += new EventHandler(Timer_Tick);
            timer.Start();
        }
        void Timer_Tick(object sender, EventArgs e)
        {
            (sender as DispatcherTimer).Stop();
            Associate();
        }
        private bool _isAssociating = false;
        private void Associate()
        {
            if (_isAssociating) return;
            _isAssociating = true;
            try
            {
                // 清除原来关联过的
                foreach (var c in _controls)
                {
                    c.KeyUp -= new KeyEventHandler(Control_KeyUp);
                }
                _controls.Clear();
                // 获取可以 Tab 的控件并加入到列表中
                IEnumerable<Control> originals = EnterToTab.FindChildren<Control>(_parent);
                foreach (var c in originals)
                {
                    if (c.IsTabStop && c.Visibility == Visibility.Visible && c.IsEnabled)
                    {
                        var t1 = c.GetType();
                        foreach (var t2 in _ctrlTypes)
                        {
                            if (t1.IsAssignableFrom(t2))
                            {
                                c.KeyUp += new KeyEventHandler(Control_KeyUp);
                                _controls.Add(c);
                                break;
                            }
                        }
                    }
                }
                // 根据 TabIndex 的原始值排序
                _controls.Sort(new TabIndexComparer());
            }
            finally
            {
                _isAssociating = false;
            }
        }
        void Control_KeyUp(object sender, KeyEventArgs e)
        {
            if ((e.Key == Key.Enter || e.Key == Key.Down) ||
                (e.Key == Key.Up))
            {
                Control source = (sender as Control);
                int index = _controls.IndexOf(source);
                if (e.Key == Key.Enter || e.Key == Key.Down)
                {
                    if (index < _controls.Count - 1)
                    {
                        _controls[index + 1].Focus();
                    }
                }
                else
                {
                    if (index > 0)
                    {
                        _controls[index - 1].Focus();
                    }
                }
            }
        }
        private class TabIndexComparer : IComparer<Control>
        {
            public int Compare(Control x, Control y)
            {
                if (x == y)
                {
                    return 0;
                }
                if (x.TabIndex <= y.TabIndex)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
        }
    }
}

本文来自bloglife的博客,原文地址:http://blog.csdn.net/bloglife/archive/2010/02/22/5316954.aspx


分享给朋友:
您可能感兴趣的文章:
随机阅读: