Click here to Skip to main content
15,900,378 members
Articles / Desktop Programming / Windows Forms

Directional Pan and Scroll Toolbox Items

Rate me:
Please Sign up or sign in to vote.
2.00/5 (2 votes)
17 Jan 2011CPOL5 min read 29.2K   474   6   7
Thoroughly documented source you can compile to a Control Library (DLL)

Introduction

A panel makes a nice container because things 'stay put' on a panel; and hooking up a panel's Click() event to a timer activated by scroll/pan buttons on that panel makes quick work of both organizing the button placement and coordinating timer start/stop events with mouse down/up events on individual buttons, provided you have a handy class like the Btn9Panel containing constructors and methods which are ready to lay out all of the details as soon as the Visual Studio designer sees it, and before it gets to your toolbox.

Background

Most of the CodeProject articles I've seen deal with intricacies which take hours to ferret out, and although sometimes there are rather obvious and simplistic solutions for beginners, most of the articles deal with relatively complex or convoluted scenarios. Obviously, a lot of the readers don't have time to fool around with simple stuff once they get done with the really tricky stuff, so I figured I ought to offer some time-saver code... Maybe something to give a poor guy a chance to get fifteen minutes of extra sleep some night.

Using the Code

All it takes is to drag a Btn9Panel out of your toolbox onto a form to see what it does. The HorizPanel and VertPanel classes subclass the Btn9Panel, and you can drag all three onto a form and use the designer to change the dimensions or FlatAppearance elements offered when FlatStyle.Flat is in use.

There isn't anything really tricky enough about the code to make an issue of it here. The NineBtnCtrl.DLL source code is so thoroughly documented (even over-documented) that you should view it in the Visual Studio IDE so that you can toggle the outlining on and off for each region as you go through it. Completely collapsing it and then examining one section at a time will take a lot less time than trying to go through it here.

The only code you need to 'wire it up' after you drag one of these panels onto a form is this:

C#
btn9Panel1.Click +=new EventHandler(btn9Panel1_Click);
btn9Panel1.Enable();

following your form's InitializeComponent() statement. And the panel Click() event handler is also required:

C#
private void btn9Panel1_Click(object sender, EventArgs e) 
{ /* Call your scroll/pan code here */ }

The example in Btn9Form.cs only carries out two operations to illustrate 'scrolling' in the handler:

C#
ii = ii + btn9Panel1.Dx; jj = jj + btn9Panel1.Dy; 

Using the Dx and Dy increments of [+|-]1 furnished by the .DLL code each time the timer ticks will allow you to pan, scroll, change array indexes, or whatever you need to do; and as long as the mouse button is held down, the timer will keep on generating these increments and calling your code. So all you need to do is to decide how you like your scrolling done; and if you don't want to use the timer for some reason, you can call SetDxDy() to set Dx and Dy for you, so you can use the same code you've got to scroll programmatically as well as in response to the mouse button events. Call btn9Panel1.Disable() whenever you want to shut down the timer response to the button presses; and be sure to check, as noted in the .DLL source code, whether BtnDown is true before calling precisely controlled code in your application if you will be enabling or disabling the timer during critical periods.

The example Windows Form in Btn9Form.cs gives you an opportunity to run a form containing a button matrix and to change the MouseOver, MouseDown, Background, Border, and Checked colors while you can see the effect it has (the designer doesn't show the MouseOver or MouseDown colors on the design surface; only in the Properties window); and after you exit the Form, you can use the Properties dialog in the designer to set the default colors or panel dimensions, although you could also hard-code the new values into the .DLL source code and recompile it if you're that devoted to your predilections.

Screenshot of Btn9Form.cs when compiled and running

Btn9Form.cs also shows you the panel name, button name, button index, and direction (W, NW, N, etc.) while two integer values are incremented/decremented during a button press. The two subclasses having only two buttons will only scroll in the N-S or E-W directions, as you might surmise, provided your scroller code follows the usual map conventions.

Points of Interest

I initially wrote some scrolling code for two separate projects which I intended ultimately to merge but which do not interoperate. One of the segments is run analogously to a modal dialog, although the threading model doesn't see it that way and there are no calls to BackgroundWorker classes since I tied the two together. I had initially used a BackgroundWorker in one and a second Thread in the other, with a rather tricky set of semaphores used to enable, configure, start, control, stop, and disable the worker thread in the former segment; and a much simpler but still analogous set of semaphores used in the latter segment, even though the latter provided bidirectional scrolling and the former did not. The difference was that the latter scrolling events were started and stopped by eight buttons (in the same form as the Btn9Panel you see featured here) which scrolled only a single graphical image window, whereas the former scrolling events were started and stopped by twelve buttons (in the same form as the VertPanel you see featured here) and would, on demand, scroll in tandem a virtual window into an Array and the visible window in a PictureBox corresponding to that and containing a bitmap representation of the array contents.

Although in merging the two segments, I replaced both the BackgroundWorker and the second Thread with a single timer, I didn't merge and subclass the arrangement of the buttons as you see them in the HorizPanel and VertPanel, nor did I create a separate class for the bidirectional Btn9Panel. These classes were created especially for this CodeProject article, just because I thought the idea of distilling the functionality embodied by those implementations into a single, easy-to-use and easy to set-up toolbox item was worth a shot.

History

The Btn9Panel development work stemmed from my project, "The CQvis MultiGradient Palette Tool", which is a freeware program which you can download from a number of sites. That has a Thread doing the scrolling in it, but does not use the Start(), Suspend(), Sleep(), or Stop() methods to initiate or terminate scrolling, as you'll see if you use WinDbg or PEBrowse Professional to examine it. That second process thread runs continuously the whole time the program is running, and its behavior is governed entirely by semaphores.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Writer, designer, inventor, musician, observer, and critic with many years of experience in each of these areas. I can do without the approval of "experts" because I believe candid statements and penetrating analysis bring greater rewards than a "pat on the back". And if I have something to say when you're not listening, I tell someone else about it.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Brian C Hart18-Jan-11 5:22
professionalBrian C Hart18-Jan-11 5:22 
GeneralComments Pin
peterchen17-Jan-11 19:38
peterchen17-Jan-11 19:38 
GeneralRe: Comments Pin
GAMerritt18-Jan-11 3:53
GAMerritt18-Jan-11 3:53 
GeneralRe: Comments Pin
peterchen18-Jan-11 8:10
peterchen18-Jan-11 8:10 
GeneralRe: Comments Pin
GAMerritt18-Jan-11 11:25
GAMerritt18-Jan-11 11:25 
There isn't any explanation there of "how easy it was to do". All the work was done already, and the only thing that was required to create those little toolbox items was to extract a few lines from my other project and make them accessible to anybody who can reference a DLL and add items to their toolbox. If you're looking for my story of "how I climbed Mount Everest", it's got nothing to do with object oriented programming or the .NET Framework, and you won't find a success story of striving to reach the pinnacle of achievement and "getting there" in an article I write dealing with anything that has to do with .NET or is object oriented.

As far as I know, on the way to achievement in .NET programming, there's only documentation, "Intellisense", and tips and articles from people who write for the CodeProject or who write books on the subject. You don't find shortcuts when identifiers are routinely concatenated into strings of 100 or more characters just to be able to unambiguously resolve references to some resource you need. I'm not thrilled with the prospect of making it look like my efforts to deal with that sort of needless complexity are substantial to the development of an article. You know as well as I do that with extra money a fellow can buy tools which enable him to avoid every bit of that complexity and write up a success story for himself just based on the goals he achieved with what he bought.

Everybody knows the basic algorithms, the data structures, the syntactical structures, etc. if they've got a decent education; and anybody who's used .NET for six months should be able to look at that article of mine and not find any concepts there which are above them or abstruse, or hard to understand. So I'm not raising their level of understanding by writing; and the source code is documented so that they won't miss a trick if they are curious enough to look at it.

You would have to argue epistemology and didactics to advance a theoretical basis for adopting a quantitative measure for the degree to which CodeProject articles are either instructive or informative, and asking what my article is "about" implies that you have some basis for that metric but haven't yet specified just what that is. If my work were mathematical in nature and lacked rigour, then a host of quantitative metrics could clearly demonstrate that. And there are similar results in logic and set theory which can demonstrate how the rhetorical structure of a piece of writing falls short of completeness. But you haven't said that's where your dissatisfaction with this article of mine lies.

If you really feel that I haven't made a significant contribution to anyone's state of knowledge by the writing of that article, that's fine. That's exactly what I think about it, too. The title is intended to suggest that there isn't any complexity at all there, and the introduction points out that everything involved is simple and "no sweat". From what I noted, you've written 19 articles for CodeProject, and I haven't seen them yet, so I don't know what YOU think is likely to be instructive. All I can tell you is that if I told you what I think is instructive, you'd want to come over here and shoot me. And although you might run across some writings of mine which really ARE instructive, you won't find them at the CodeProject, in spite of the fact that nearly every article I've read on CodeProject pages has been very instructive and intriguing. I don't intend to try to convince anyone at CP of anything having to do with my REAL thesis about computer science. Like I say, you'd want to come all the way over here from Germany and shoot me.
GeneralRe: Comments Pin
peterchen18-Jan-11 11:58
peterchen18-Jan-11 11:58 
GeneralRe: Comments Pin
GAMerritt18-Jan-11 14:08
GAMerritt18-Jan-11 14:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.