Search code examples
c#formstreeview

How to create an options form in C# Windows Forms?


https://i.sstatic.net/v58ov.png

See the picture above. This is a screenshot from Visual Studio's options form.

The left side is essentially a TreeView. The right side is various controls that change program options. When nodes in the TreeView are selected, the right side changes, showing different options.

How do you program something like this? Does the right side just have 50 overlapping panels, and the selecting of nodes just changes which panel is visible? If this is the case, how would you go about managing such? It would be a mess in the designer.


Solution

  • No you don't make 50 overlapping panels. Just create several usercontrols and, for example, link the types on the tag of a node. You can use the Activator to create the controls. Create 1 treeview and 1 panel: (PSEUDO CODE)

    // create nodes:
    TreeNode item = new TreeNode();
    
    item.Tag = typeof(UserControl1);
    
    TreeView.Nodes.Add( item );
    
    
    // field currentControl
    UserControl _currentControl;
    
    
    // on selection:
    TreeViewItem item = (TreeViewItem)sender;
    
    if(_currentControl != null)
    {
       _currentControl.Controls.Remove(_currentControl);
       _currentControl.Dispose();
    }
    
    // if no type is bound to the node, just leave the panel empty
    if (item.Tag == null)
      return;
    
    _currentControl = (UserControl)Activator.Create((Type)item.Tag);
    Panel1.Controls.Add(_currentControl);
    

    The next question would be, "I'd like to call a save method, or RequestClose method in the controls". For this, you should implement an Interface on the controls, and when you switch nodes, just try to cast the _currentusercontrol to IRequestClose interface and call, for example, bool RequestClose(); method.

     // on selection:
     TreeViewItem item = (TreeViewItem)sender;
    
     if(_currentControl != null)
     {
        // if the _currentControl supports the IRequestClose interface:
        if(_currentControl is IRequestClose)
            // cast the _currentControl to IRequestCode and call the RequestClose method.
            if(!((IRequestClose)_currentControl).RequestClose())
                 // now the usercontrol decides whether the control is closed/disposed or not.
                 return;
    
        _currentControl.Controls.Remove(_currentControl);
        _currentControl.Dispose();
     }
    
     if (item.Tag == null)
       return;
    
    _currentControl = (UserControl)Activator.Create(item.Tag);
    Panel1.Controls.Add(_currentControl);
    

    But this will be the next step.