如何在 C# 中创建树视图首选项对话框类型的界面?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-07-31 13:38:43  来源:igfitidea点击:

How to create a tree-view preferences dialog type of interface in C#?

提问by Dylan Bennett

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.

我正在编写一个基本上只是一个首选项对话框的应用程序,很像 Visual Studio 本身使用的树视图首选项对话框。该应用程序的功能只是将数据从串行设备传递到文件。它在将数据写入文件之前对数据执行很多很多转换,因此应用程序的 GUI 只是指示这些转换应该是什么的所有设置。

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 lotof extra work. Am I doing this in a totally stupid way? Is there some "obvious" easier way of doing this that I'm missing?

基本上我必须使用这个巨大的表单,到处都是容器控件,然后进行大量的运行时重新格式化以使其全部工作。这似乎是很多额外的工作。我是否以一种完全愚蠢的方式这样做?是否有一些我缺少的“明显”更简单的方法来做到这一点?

采纳答案by xyz

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

一种更整洁的方法是为每个“窗格”创建单独的表单,并在每个表单构造函数中设置

this.TopLevel = false;
this.FormBorderStyle = FormBorderStyle.None;
this.Dock = 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 SplitContainerwith a static TreeViewin one panel, and space to add these forms in the other. Once they are added, they could be flipped through using Hide/Showor BringToFront/SendToBackmethods.

也许主表单可以在一个面板中使用SplitContainer带有静态的 a TreeView,并在另一个面板中使用空间来添加这些表单。添加它们后,它们可以通过使用Hide/ShowBringToFront/SendToBack方法进行翻转。

SeparateForm f = new SeparateForm(); 
MainFormSplitContainer.Panel2.Controls.Add(f); 
f.Show();

回答by Dylan Bennett

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 completelyseparate. This means I don't get overlap on the snapping guidelines and other design time advantages.

我喜欢 Duncan 的回答,因为这意味着每个节点界面的设计可以保持完全独立。这意味着我不会在捕捉指南和其他设计时间优势上重叠。

回答by Peteter

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.

我可能会基于继承 CustomControl 的基类创建几个面板类。这些控件将具有诸如 Save/Load 之类的方法。如果是这样,我可以分别设计这些面板中的每一个。

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 :-)

我使用了一个向导控件,它在设计模式下处理多个页面,以便可以在设计器中单击下一步并通过设计器一次设计所有页面。尽管这在将代码连接到控件时有几个缺点,但这可能意味着您可以通过构建一些设计器类来进行类似的设置。我自己从来没有在 VS 中编写过任何设计器类,所以我不能说如何或者它是否值得:-)

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.

另一种方法当然是在请求每个页面时生成 gui 代码,使用有关设置类型的信息。