Richie 的个人资料The Sandpit - "We hack s...日志列表 工具 帮助
5月13日

Adding Tab-key Support to the PropertyGrid Control

The PropertyGrid control is convenient for adding object editing support with minimal code.  However, for some reason it does not support property navigation with the tab key.  Instead, clicking tab key will progressively set focus to other controls in your form.  This post provides a simple subclassed PropertyGrid with support for tab-key navigation of properties.

image

Below is the source code to a subclassed PropertyGrid control called TabbedPropertyGrid.  There were two major issues that needed to be overcome.  The first is that the PropertyGrid does not raise any keyboard events, to workaround this the subclassed PropertyGrid must hijack keyboard events from the parent form.  The second issue is that there is no intuitive way to navigate GridItems.  However, this MSDN forum thread provided a few clues to solve this using the Griditems and Parent property.

public class TabbedPropertyGrid : PropertyGrid {
    public TabbedPropertyGrid() : base() { }
    public void SetParent(Form form) {
        // Catch null arguments
        if (form == null) {
            throw new ArgumentNullException("form");
        }

        // Set this property to intercept all events
        form.KeyPreview = true;

        // Listen for keydown event
        form.KeyDown += new KeyEventHandler(this.Form_KeyDown);
    }
    private void Form_KeyDown(object sender, KeyEventArgs e) {
        // Exit if cursor not in control
        if (!this.RectangleToScreen(this.ClientRectangle).Contains(Cursor.Position)) {
            return;
        }

        // Handle tab key
        if (e.KeyCode != Keys.Tab) { return; }
        e.Handled = true;
        e.SuppressKeyPress = true;

        // Get selected griditem
        GridItem gridItem = this.SelectedGridItem;
        if (gridItem == null) { return; }

        // Create a collection all visible child griditems in propertygrid
        GridItem root = gridItem;
        while (root.GridItemType != GridItemType.Root) {
            root = root.Parent;
        }
        List<GridItem> gridItems = new List<GridItem>();
        this.FindItems(root, gridItems);

        // Get position of selected griditem in collection
        int index = gridItems.IndexOf(gridItem);

        // Select next griditem in collection
        this.SelectedGridItem = gridItems[++index];
    }
    private void FindItems(GridItem item, List<GridItem> gridItems) {
        switch (item.GridItemType) {
            case GridItemType.Root:
            case GridItemType.Category:
                foreach (GridItem i in item.GridItems) {
                    this.FindItems(i, gridItems);
                }
                break;
            case GridItemType.Property:
                gridItems.Add(item);
                if (item.Expanded) {
                    foreach (GridItem i in item.GridItems) {
                        this.FindItems(i, gridItems);
                    }
                }
                break;
            case GridItemType.ArrayValue:
                break;
        }
    }
}

After adding the TabbedPropertyGrid to your form, the form must be parsed into the control using the SetParent method.

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();

        // Assign the form to the propertygrid
        this.tabbedPropertyGrid1.SetParent(this);
        this.tabbedPropertyGrid1.SelectedObject = this;
    }
}

Known Issues:  Shift-Tab does not select properties in reverse order.

Technorati Tags: ,,

评论

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。
Carmichael​Richie 在此页禁用了评论功能。

引用通告

引用此项的网络日志