Question

I have one BIG .ini file. e.c :

[Globals]
EdgeDkShadowColor = 188 196 218
EdgeFillColor = 244 244 244

[SysMetrics]
ActiveCaption = 207 214 232
Background = 58 110 165
Btnface = 244 244 244
...

[Button.Checkbox]
AccentColorHint = 250 196 88
Bgtype = imagefile
BorderColorHint = 29 82 129
FillColorHint = 33 161 33
...

[Button.Checkbox(Checkeddisabled)]
TextColor = 161 161 146

[Button.Checkbox(Mixeddisabled)]
TextColor = 161 161 146

[Button.Checkbox(Uncheckeddisabled)]
TextColor = 161 161 146

And i create static class. I want enumerate lines of .ini and set value to all fields from class Parameters.

Class structure is:

public static class Parameters
{
    public static class Globals
    {
        public static string EdgeDkShadowColor;
        public static string EdgeFillColor;
        ...
    }

    public static class SysMetrics
    {
        public static string ActiveCaption;
        public static string Background;
        public static string Btnface;
        ...
    }

    public static class Button
    {
        public static class Checkbox
        {
            public static string AccentColorHint;
            public static string Bgtype;
            public static string BorderColorHint;
        }

        public static class Checkbox_Checkeddisabled
        {
            public static string TextColor;
        }

        public static class Checkbox_Mixeddisabled
        {
            public static string TextColor;
        }

        public static class Checkbox_Uncheckeddisabled
        {
            public static string TextColor;
        }
        ...

How can I correctly enumerate all fields from class and initialize them to eventually get an object:

Parameters.
Globals.
    EdgeDkShadowColor = "188 196 218";
    EdgeFillColor = "244 244 244";
SysMetrics.
    ActiveCaption = "207 214 232"
    Background = "58 110 165"
    Btnface = "244 244 244"
    ...
Button.
    Checkbox.
        AccentColorHint = "250 196 88"
        Bgtype = "imagefile"
        BorderColorHint = "29 82 129"
        ...       etc.

P.S.

  1. All values is string.
  2. '(' in name of replaced by '_'.
  3. Name of parameter can contain a string "::". It is replaced by "Ext".

UPDATE

I found first code of this task. I try to use this function: The main part of the code is

StringReader str = new StringReader(fileAsString);
string line;
Type curType = null;
while ((line = str.ReadLine()) != null)
{
if (string.IsNullOrEmpty(line) | line.StartsWith(";")) continue;
if (line.Contains('['))
{
    line = line[0] + line[1].ToString().ToUpper() + line.Substring(2);
    var listing = typeof(Parameters).GetNestedTypes().ToList();
    string lineS = line.Trim('[').Trim(']').Trim(')').
                        Replace("(", "_").Replace("::", "Ext").Trim();
    var listingOf = listing.Find(tipe => tipe.Name == lineS);
    curType = listingOf;
}
else
{
    if (curType != null)
    {
        FieldInfo found = curType.GetField(splits[0].Trim(')').Replace("(", "_").Trim());
        if (found != null)
            found.SetValue(null, splits[1].Trim());
    }
}
}

It's work, but only for one level. This is result of work this code:

http://postimg.org/image/5s28m4c8h/

Was it helpful?

Solution 2

Solution found:

string bytePath = resPath + themesIni;

if (!File.Exists(bytePath))
{
    if (foundRow != null) bytePath = resPath + @"\" + foundRow.ItemArray[1] + @"\" + themesIni;
}
byte[] arr = File.ReadAllBytes(bytePath);
string fileAsString = new UnicodeEncoding().GetString(arr);
StringReader str = new StringReader(fileAsString);
string line;
Type curType = null;
Type parentType = null;
while ((line = str.ReadLine()) != null)
{
    if (string.IsNullOrEmpty(line) | line.StartsWith(";")) continue;
    if (line.Contains('['))
    {
        line = (line[0] + line[1].ToString().ToUpper() + line.Substring(2))
            .Trim('[').Trim(']').Trim(')').Replace("(", "_").Replace("::", "Ext").Trim();
        string[] splitLines = line.Split('.');
        //splitLines[0] = 
        //    (splitLines[0][0] + splitLines[0][1].ToString().ToUpper() + splitLines[0].Substring(2))
        //    .Trim('[').Trim(']').Trim(')').Replace("(", "_").Replace("::", "Ext").Trim();
        //splitLines[1] = 
        //    (splitLines[1][0] + splitLines[1][1].ToString().ToUpper() + splitLines[1].Substring(2))
        //    .Trim('[').Trim(']').Trim(')').Replace("(", "_").Replace("::", "Ext").Trim();
        if (splitLines.Length > 1)
        {
            if (parentType == null)
            {
                parentType = typeof(Parameters).GetNestedTypes().ToList()
                    .Find(tipe => tipe.Name == splitLines[0]);
                List<Type> listing = parentType.GetNestedTypes().ToList();
                curType = listing.Find(tipe => tipe.Name == splitLines[1]);
            }
            else
            {
                List<Type> listing = parentType.GetNestedTypes().ToList();
                curType = listing.Find(tipe => tipe.Name == splitLines[1]);
            }
        }
        else
        {
            parentType = null;
            List<Type> listing = typeof (Parameters).GetNestedTypes().ToList();
            string lineT = line;
            Type listingOf = listing.Find(tipe => tipe.Name == lineT);
            curType = listingOf;
        }
    }
    else
    {
        string[] splits = line.Split('=');
        splits[0] = splits[0].Substring(0, 1).ToUpper() + splits[0].Substring(1);
        if (curType != null)
        {
            FieldInfo found = curType.GetField(splits[0].Trim(')').Replace("(", "_").Trim());
            if (found != null)
                found.SetValue(null, splits[1].Trim());
        }
    }
}

OTHER TIPS

This sounds like a good candidate for reflection. Basically you'd read each line of the INI file, keeping track of the depth based on the '.' delimiter in the configuration, then try and find a matching property on your class based on the depth... If you do, populate it with the value. I did something like this with an Expression Tree recently... For each string separated by a '.' character, access a property or field with that name and then try and find the next one on that property... A code sample would be fairly insane to give but that's definitely how I'd approach it... Reflection since the pattern is that your class's properties and sub properties match the naming convention in the INI file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top