/// <summary>
 /// Bind this settings object to WPF controls. Supported mappings: bool to CheckBox, enum to RadioButtons or ListBoxItems, string, double, float, int to TextBox
 /// </summary>
 /// <param name="dataContext">The WPF element that contains all the controls required for binding</param>
 /// <param name="autoUpdateSettingsObject">Whether to attach event handlers to automatically apply changes in the GUI to the settings object</param>
 public void Bind(GUIAdapter dataContext, bool autoUpdateSettingsObject = true)
 {
     _dataContext = dataContext;
     updateMappings(autoUpdateSettingsObject);
 }
        // TODO Automatically read default values and write to default config if none exists at startup.
        public void updateMappings(bool autoUpdateSettingsObject = true)
        {
            Dictionary <string, PropertyMapping> mappingsNew = new Dictionary <string, PropertyMapping>();

            GUIAdapter dataContext = _dataContext;

            FieldInfo[] members = this.GetType().GetFields();
            foreach (FieldInfo member in members)
            {
                Type fieldType = member.FieldType;
                //MessageBox.Show(member.Name);
                Control  controlInfo  = (Control)member.GetCustomAttribute(typeof(Control));
                Category categoryInfo = (Category)member.GetCustomAttribute(typeof(Category));


                // Enums get special treatment
                if (fieldType.IsSubclassOf(typeof(System.Enum)))
                {
                    PropertyMappingEnum propertyMapping = new PropertyMappingEnum();
                    if (categoryInfo != null)
                    {
                        propertyMapping.categoryName = categoryInfo.getCategoryName();
                    }
                    propertyMapping.fieldInfo    = member;
                    propertyMapping.fieldType    = fieldType;
                    propertyMapping.defaultValue = member.GetValue(this);
                    FieldInfo[] enumMembers    = member.FieldType.GetFields();
                    int[]       enumValues     = (int[])member.FieldType.GetEnumValues();
                    int         enumValueIndex = 0;
                    for (int i = 0; i < enumMembers.Length; i++)
                    {
                        FieldInfo enumMember = enumMembers[i];
                        if (fieldType == enumMember.FieldType)
                        {
                            int enumValue = enumValues[enumValueIndex++];

                            Control controlInfoHere = (Control)enumMember.GetCustomAttribute(typeof(Control));
                            if (controlInfoHere == null)
                            {
                                throw new Exception("Enum member " + enumMember.Name + " has no Control attribute set. No binding posssible. If you wish to explicitly use a settings value that doesn't have a WPF representation, use [Control(null)].");
                            }
                            propertyMapping.mappedNames.Add(enumValue, controlInfoHere.getSourceElement());


                            string localCopyOfMemberNameForLambda = member.Name;
                            if (controlInfoHere.getSourceElement() != null)
                            {
                                _dataContext.attachEventHandler(controlInfoHere.getSourceElement(), (a) => {
                                    if (autoUpdateSettingsObject)
                                    {
                                        readSingleValueFromGUI(localCopyOfMemberNameForLambda);
                                    }
                                    OnValueUpdatedInGUI(new ValueUpdatedEventArgs(localCopyOfMemberNameForLambda));
                                });
                            }
                        }
                    }
                    mappingsNew.Add(member.Name, propertyMapping);
                }
                else
                {
                    if (controlInfo == null)
                    {
                        throw new Exception("Field " + member.Name + " has no Control attribute set. No binding posssible. If you wish to explicitly use a settings value that doesn't have a WPF representation, use [Control(null)].");
                    }

                    PropertyMapping propertyMapping = new PropertyMapping(controlInfo.getSourceElement());
                    propertyMapping.fieldType    = fieldType;
                    propertyMapping.fieldInfo    = member;
                    propertyMapping.defaultValue = member.GetValue(this);
                    if (categoryInfo != null)
                    {
                        propertyMapping.categoryName = categoryInfo.getCategoryName();
                    }

                    string localCopyOfMemberNameForLambda = member.Name;
                    if (controlInfo.getSourceElement() != null)
                    {
                        _dataContext.attachEventHandler(controlInfo.getSourceElement(), (a) => {
                            if (autoUpdateSettingsObject)
                            {
                                readSingleValueFromGUI(localCopyOfMemberNameForLambda);
                            }
                            OnValueUpdatedInGUI(new ValueUpdatedEventArgs(localCopyOfMemberNameForLambda));
                        });
                    }

                    mappingsNew.Add(member.Name, propertyMapping);
                }
            }
            mappings = mappingsNew;
        }