Automatic runtime tab Order Management for Windows Forms

Source: Internet
Author: User
ArticleDirectory
    • Tabschemeprovider usage
    • Tabschemeprovider implementation

 

 

This article presents the tabordermanager, which is a class that automatically adjusts the tab order on a Windows form based on different high-level schemes.

 

    • Download source-38.5 KB

Introduction

Good tab orders on your Form S are important. they allow experienced users to more rapidly interact with your application, and they may even be necessary to enable your application for users that cannot manipulate the mouse. you may sometimes find it desirable to set the tab order at runtime. for example, you may allow your users to customize the visibility or position Form Controls, and you 'd like a professional tab order even when you don't know exactly how the final Form Will look. Or you may not want to have to worry about maintaining the tab order for Complex Form S at design-time as the design changes. Tabordermanager Class will help you easily automate the process of applying a nice tab order at runtime. And Tabschemeprovider Component makes it simple to set up your tabbing strategies in the windows Form S designer.

Background

This article assumes a basic familiarity with WindowsFormS programming in the. NET Framework Using C # Or Visual Basic. net.

Using the code

the tabordermanager class is currently available in both C # and Visual Basic. net. it's quite simple: Given a container control (probably a form , but possibly a groupbox , tabcontrol , panel , etc .), calling the settaborder method will automatically adjust the tabindex Properties on child controls to implement a tab order that is either primarily "setting ss the container, then down "or" down the container, then restart SS ". by default, this strategy is inherited by child container controls. however, using the setschemeforcontrol method, you can override the strategy for specific iners. one situation where this is useful is when you wowould like users to tab through a series of groupbox es generation SS-first, but Tab through set of enclosed textbox es down-first.

Here is an example invocation ofTabordermanagerTo set an Alibaba SS-first tabbing strategy in C #:

Collapse | Copy code
 
//In constructor after initializecomponent (or whatever other//Code might set controls 'tabindex properties ).(NewTabordermanager (This). Settaborder (tabordermanager. tabscheme. Sort ssfirst );

And in Visual Basic. Net:

Collapse | Copy code
'// In constructor after initializecomponent (or whatever'// Other code might set controls 'tabindex properties ).DimTomAsTabordermanager =NewTabordermanager (Me) Tom. settaborder (tabordermanager. tabscheme. acrossfirst)
Implementation

to implement a given Tab Scheme strategy, we need to sort the controls and then set their tab order. the key is how the controls are sorted. if the primary scheme is "Your SS the container, then down", our primary sorting priority is by the controls ' top property values. if and only if the top properties are the same, then we fall back to sorting on the left property values. the converse is true for the "down the container, then sans SS" tabbing scheme. we use. net Framework's built-in ability to sort collections based on a custom icomparer implementation. our icomparer is called tabschemecomparer , and its compare method implements the sorting strategy described above.

If a given control is itself a container (that is, it has child controls), we need to recurse. if the scheme override functionality is being used, we need to check whether or not we need to change the tab scheme at each level of the recursion. tab scheme overrides for individual containers are tracked usingHashtableThat lives inTabordermanagerThat the user creates. When we recurse, we create a newTabordermanagerAnd pass the overrides down. The process of creating AuxiliaryTabordermanagerS is invisible to the client code. To see a tab scheme override in action, you may choose to add a down-first override to the group box inside the tab control of the demo application.

The tabschemeprovider component

You may also want to configure your tab schemes in the windowsFormS designer without having to write any code.TabschemeproviderComponent is a thin wrapper aroundTabordermanagerClass to allow you to do just that.TabschemeproviderImplementsIextenderproviderInterface to dynamically AddTabschemeProperty to your container controls. A complete discussionIextenderproviderIs beyond the scope of this article. Here, I will simply explain how you can take advantage ofTabschemeproviderFunctionality and discuss the interesting implementation details.

Tabschemeprovider usage

In the specified ded solution, Taborder Class Library project contains both Tabordermanager Class and Tabschemeprovider Component. After you build this project, you can then add Tabschemeprovider Component to your windows Form S toolbox by right-clicking, choosing Add/Remove items, and browsing to Taborder. dll Assembly that you compiled. Once it's on the toolbox, you may drag and drop it onto a Windows Form . There it sits in the component tray. But if you now examine the Properties window for your Form , Groupbox Es, Panel S, orUsercontrol S, you will see a new Tabscheme Property which you can set None (The default ), Acrossfirst , Or Downfirst . At runtime, during FormLoad Event, the selected tab scheme for each container will propagate down through its Child controls as though you had Tabordermanager. settaborder On the containers in question.

Tabschemeprovider implementation

there are some implementation details for the tabschemeprovider control that are worth noting. as I stated above, the tabschemeprovider gets its interesting functionality from the tabordermanager class. thus, getting it to work is just a matter of creating a tabordermanager instance for the top-level form , adding overrides for all other container controls with the tabscheme property set, and calling tabordermanager. settaborder In the form load event (which occurs after the form -designer-generated code has positioned all of the controls in the form 's control hierarchy ).

the surprisingly difficult part is getting a reference to the top-level form whose load event we need. components like the tabschemeprovider are not sited on the form at runtime, and therefore do not automatically have access to the control hierarchy. this is in contrast to Control S, which have properties like control. parent or control. toplevelcontrol . for the purposes of the tabschemeprovider component, when the form itself is one of the controls whose tab order needs to be set, this is not a problem. in that case, the designer generates a line of code like the following:

Collapse | Copy code
 
// //DemoForm// This. Tabschemeprovider1.settabscheme (This, Smcmaster. tabordermanager. tabscheme. datagssfirst );

The Tabschemeprovider Can detect that Tabscheme Of Form Is being set and use the given Form Instance to wire up Load Event handler. Case closed. But what happens when Form Has the default tab scheme Tabordermanager. tabscheme. None ? In that case, no such line of code is generated by the designer, and it is no longer clear from where Tabschemeprovider Can obtain its Form Instance. One might think that when Settabscheme Is called for non-Form Controls, you coshould just grab Form Reference out of Control. toplevelcontrol Property. Unfortunately, this does not work, because in general, Settabscheme May get called before Control And/or its parents have been added to Form , And Control. toplevelcontrol Is Null In that situation.

One solution to this problem wowould have been to removeDefaultvalueAttribute from the extender'sTabschemeProperty, upgrade tively forcing the windowsFormS designer to generateSettabschemeCall for each and every supported container control including the top-levelForm. This isn' t very satisfying. So, I worked until I came up with an alternative.

The final implementation recognizes that there are two possibilities whenTabschemeproviderComponent is notified via a callSettabschemeThat a container wants its tab order managed:

  1. the control is already a part of the form 's control hierarchy (where the case where the control is the form ). then we can directly and immediately obtain a reference to the form and hook its load event.
  2. the control is not already a part of the form 's control hierarchy. here, we hook the parentchanged event for the control and for all of its ancestors. eventually, the control or one of its ancestors will be added to the form , and we can hook the form 's load event in the resulting parentchanged handler.

When we finally do discoverFormReference via the handling of either of the two possibilities, we have the inFormAtion we need and can short-circuit further processingParentchangedEvents.

Finally, if you use more than oneTabschemeproviderOn a givenForm, The resulting tab order will depend on the order in which they processFormLoadEvent. In other words, the behavior is undefined, So you shoshould avoid this scenario.

History
    • Initial Release: 09/28/2004
    • AddedTabschemeproviderComponent: 10/28/2004

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.