tags:

views:

1112

answers:

4

I'm writing an application that is basically just a preferences dialog much like the tree-view preferences dialog that Visual Studio itself uses. The function of the application is simply a pass-through for data from a serial device to a file. It performs many, many transformations on the data before writing it to the file, so the GUI for the application is simply all the settings that dictate what those transformations should be.

What's the best way to go about designing/coding a tree-view preferences dialog? The way I've been going about it is building the main window with a docked tree control on the left. Then I have been creating container controls that correspond to each node of the tree. When a node is selected, the app brings that node's corresponding container control to the front, moves it to the right position, and maximizes it in the main window. This seems really, really clunky while designing it. It basically means I have tons of container controls beyond the edge of the main window during design time that I have to keep scrolling the main window over to in order to work with them. I don't know if this totally makes sense the way I'm writing this, but maybe this visual for what I'm talking about will make more sense:

form design

Basically I have to work with this huge form, with container controls all over the place, and then do a bunch of run-time reformatting to make it all work. This seems like a lot of extra work. Am I doing this in a totally stupid way? Is there some "obvious" easier way of doing this that I'm missing?

+5  A: 

A tidier way is to create separate forms for each 'pane' and, in their constructor, set

Form.TopLevel = false;
Form.FormBorderStyle = FormBorderStyle.None;
Form.DockStyle = DockStyle.Fill;

That way, each of these forms can be laid out in its own designer, instantiated one or more times at runtime, and added to the empty area like a normal control.

Perhaps the main form could use a SplitContainer with a static TreeView in one panel, and space to add these forms in the other. Once they are added, they could be flipped through using Hide/Show or BringToFront/SendToBack.

SeparateForm f = new SeparateForm(); 
MainFormSplitContainer.Panel2.Controls.Add(f);
f.Show();
frou
+1  A: 

Greg Hurlman wrote:

Why not just show/hide the proper container when a node is selected in the grid? Have the containers all sized appropriately in the same spot, and hide all but the default, which would be preselected in the grid on load.

Unfortunately, that's what I'm trying to avoid. I'm looking for an easy way to handle the interface during design time, with minimal reformatting code needed to get it working during run time.

I like Duncan's answer because it means the design of each node's interface can be kept completely separate. This means I don't get overlap on the snapping guidelines and other design time advantages.

Dylan Bennett
A: 

Dylan wrote:

I like Duncan's answer because it means the design of each node's interface can be kept completely separate. This means I don't get overlap on the snapping guidelines and other design time advantages.

Yeah, me too - what can I say, I'm mostly a backend/ASP.Net guy. :)

Greg Hurlman
A: 

I would probably create several panel classes based on a base class inheriting CustomControl. These controls would then have methods like Save/Load and stuff like that. If so I can design each of these panels separately.

I have used a Wizard control that in design mode, handled several pages, so that one could click next in the designer and design all the pages at once through the designer. Though this had several disadvantages when connecting code to the controls, it probably means that you could have a similar setup by building some designer classes. I have never myself written any designer classes in VS, so I can't say how to or if its worth it :-)

I'm a little curious of how you intend to handle the load/save of values to/from the controls? There must be a lot of code in one class if all your pages are in one big Form?

And yet another way would of course be to generate the gui code as each page is requested, using info about what type of settings there are.

Peteter