public static Boolean EditConfiguration(IWin32Window Owner, GenericConfiguration Config) {
            using (ConfigurationForm form = new ConfigurationForm()) {
                form.ShowConfiguration(Config);
                if (form.ShowDialog(Owner) == DialogResult.OK) {
                    form.SaveConfiguration();
                    return true;
                }
            }

            return false;
        }
        private void AddConfigurationEntriesToTable(GenericConfiguration Config) {
            // Build entry groups (GroupKey)
            Int32 first_row = Table.RowCount;
            Int32 total_rows = 0;
            Dictionary<Object, List<ConfigurationEntry>> groups = new Dictionary<Object, List<ConfigurationEntry>>();
            foreach (ConfigurationEntry entry in Config) {
                // Ignore entries that don't want to be edited or shown
                if (entry.ControlType == ConfigurationEntry.ControlTypes.None)
                    continue;

                // Make sure that the object used as key in the dictionary is not null
                Object group = (entry.GroupKey == null ? "" : entry.GroupKey);

                // Initialize a new group in the dictionary
                if (!groups.ContainsKey(group)) {
                    groups[group] = new List<ConfigurationEntry>();
                    total_rows++;
                }

                // Add the entry to the dictionary
                groups[group].Add(entry);
                total_rows++;

                // If there is a SubText, it needs to be counted, too
                if (!String.IsNullOrEmpty(entry.SubText))
                    total_rows++;
            }

            // Sort the grouped lists (SortKey)
            foreach (List<ConfigurationEntry> list in groups.Values) {
                list.Sort((a, b) => a.SortKey - b.SortKey);
            }

            // Increase the row counter for the final label (see the end of this method)
            total_rows++;

            // Setup the container panel
            Table.RowCount += total_rows;
            UpdateTableStyles(first_row);

            // Create the necessary controls
            Int32 row = first_row;
            foreach (KeyValuePair<Object, List<ConfigurationEntry>> kv in groups) {
                // Add a group heading, if it is not empty
                // (it is made sure that group is not null further up)
                String group = kv.Key.ToString();
                if (!String.IsNullOrEmpty(group)) {
                    AddHeadingToRow(group, row, true);
                    row++;
                }

                // Add the value rows
                foreach (ConfigurationEntry entry in kv.Value) {
                    switch (entry.ControlType) {
                        case ConfigurationEntry.ControlTypes.TextBox:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddTextBoxToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.MultiLineTextBox:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddMultilineBoxToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.ComboBox:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddComboBoxToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.ComboBoxAsLinkLabel:
                        case ConfigurationEntry.ControlTypes.ButtonAsLinkLabel: 
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddLinkLabelToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.CheckBox:
                            ControlMapping[entry] = AddCheckBoxToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.Label:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddLabelToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.GenericConfiguration:
                        case ConfigurationEntry.ControlTypes.Button:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddButtonToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.Slider:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddLabelSliderToRow(entry, row);
                            break;
                        case ConfigurationEntry.ControlTypes.File:
                        case ConfigurationEntry.ControlTypes.Directory:
                            AddHeadingToRow(entry.Text, row, false);
                            ControlMapping[entry] = AddFileSystemBrowserToRow(entry, row,
                                entry.ControlType == ConfigurationEntry.ControlTypes.Directory);
                            break;
                        default:
                            throw new ArgumentException(String.Format("Unknown input type: {0}", entry.ControlType));
                    }
                    entry.PropertyChanged += UpdateControlWithNewValue;
                    row++;

                    if (!String.IsNullOrEmpty(entry.SubText)) {
                        AddSubTextLabelToRow(entry, row);
                        row++;
                    }
                }
            }

            // Add a final label with no text to add some extra spacing
            AddHeadingToRow("", row, false);
        }
        /// <summary>
        /// Creates a configuration for a given object by using its properties and the <see cref="ConfigurationAttribute"/>.
        /// </summary>
        /// <param name="BoundObject">The object for which a set of configuration entries should be created.</param>
        /// <returns>An instance of the <see cref="GenericConfiguration"/> class that is bound the the given object.</returns>
        public static GenericConfiguration CreateFor(Object BoundObject) {
            GenericConfiguration config = new GenericConfiguration();
            config.BoundObject = BoundObject;

            Type t = GetDirectType(BoundObject);
            foreach (PropertyInfo prop in t.GetProperties()) {
                config.AddByPropertyWithAttribute(BoundObject, prop);
            }

            return config;
        }
 void ShowConfiguration(GenericConfiguration Config) {
     Configuration = Config;
 }
        /// <summary>
        /// Creates a configuration for a given type. The type must be a class.
        /// </summary>
        /// <param name="type">The type that defines the configuration entries.</param>
        /// <returns>An instance of the <see cref="GenericConfiguration"/> class that contains the configuration entries as defined by the given type.</returns>
        /// <exception cref="System.ArgumentException">Thrown when <paramref name="type"/> is not a class type.</exception>
        public static GenericConfiguration CreateFor(Type type) {
            if (!type.IsClass)
                throw new ArgumentException("The passed type must be a class.", "type");

            GenericConfiguration config = new GenericConfiguration();

            foreach (PropertyInfo prop in type.GetProperties()) {
                config.AddByPropertyWithAttribute(null, prop);
            }

            return config;
        }