WPF, please, how can I save names from a listbox to a * .ini file.

jack pelon 96 Reputation points
2020-09-26T01:47:21.827+00:00

Hello and good morning. How can I do so that the names of the files selected in the Listbox by a "checkbox" can be written and saved in a * .ini file for example: (ListTextFile.ini)? Also with button update the list in case to put more names in the listbox. I am very grateful for the help you can give me.

I attach an image and the demo of the project.

Link Demo Edit: https://drive.google.com/file/d/17CpKVVXZx5l7aGPd6255lkDDJUI5bRRV/view?usp=sharing

28453-3.jpg

Developer technologies Windows Presentation Foundation
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2020-10-19T05:33:41.06+00:00

    Hi,
    here is a new version:

    In your code (CodeBehind of MainWindow) change:

    private void Save_Click(object sender, RoutedEventArgs e)
    {
      if (myList.ItemsSource == null) return;
      ConfigClass cfg = new ConfigClass(this.ini_file_root.Text);
      List<string> ltForSave = new List<string>();
      foreach (MyModel obj in myList.ItemsSource)
        cfg.SetValue("ListText.Files", "TextActive", obj.Name, !obj.StatusForCheckBox);
      cfg.Save();
    }
    

    and new version of config class (I include comment - uncomment functionality):

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text.RegularExpressions;
    using System.Xml.Linq;
    
    namespace ListTxt
    {
      /// <summary>class for ini files</summary> 
      public class ConfigClass
      {
    
        #region Fields
        /// <summary>content of ini in xml</summary>
        private XElement config = new XElement("config");
    
        /// <summary>char for identification of comment, first char is default</summary>
        private string CommentCharacters = ";";
    
        /// <summary>regex to identify comment</summary>
        private string regCommentStr = "";
        private Regex regComment;
    
        /// <summary>reges to identiy element</summary>
        private Regex regEntry;
    
        /// <summary>regex to identiy header</summary>
        private Regex regCaption;
    
        #endregion
    
        #region constructors
    
        /// <summary>empty constructor</summary>
        public ConfigClass()
        {
          regCommentStr = @"(\s*[" + CommentCharacters + "](?<comment>.*))?";
          regComment = new Regex(regCommentStr);
          regEntry = new Regex(@"^[ \t]*(?<entry>([^=])+)=(?<value>([^=" + CommentCharacters + "])+)" + regCommentStr + "$");
          regCaption = new Regex(@"^[ \t]*(\[(?<section>([^\]])+)\]){1}" + regCommentStr + "$");
        }
    
        /// <summary>constructor to read ini file</summary>
        /// <param name="filename">name fo inifile</param>
        public ConfigClass(string fileName) : this()
        {
          if (!File.Exists(fileName)) throw new IOException($"File {fileName}  not found");
          this.FileName = fileName;
          LoadIniToXML();
        }
    
        #endregion
    
        /// <summary>save ini file</summary>
        /// <returns></returns>
        public bool Save()
        {
          if (string.IsNullOrEmpty(this.FileName)) return false;
          try { SaveXMLToIni(); }
          catch (Exception ex) { throw new IOException($"error writing ini file {this.FileName}", ex); }
          return true;
        }
    
        /// <summary>full file name</summary>
        public string FileName { get; set; }
    
        /// <summary>directory of file</summary>
        public string Directory
        {
          get
          {
            if (System.IO.Directory.Exists(this.FileName)) return Path.GetDirectoryName(this.FileName);
            return string.Empty;
          }
        }
    
    
        /// <summary>comment entry</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="entry">name of entry in section</param>
        /// <returns>true if entry was found in section</returns>
        public bool CommentValue(string section, string entry)
        {
          var res = from en in (from sec in config.Elements() where sec.Attribute("name").Value == section select sec).Elements(entry) select en;
          if (res.Count() != 1) return false;
          res.First().Value = CommentCharacters[0] + res.First().Name.ToString() + "=" + res.First().Attribute("name").Value;
          res.First().Name = "comment";
          return true;
        }
    
        /// <summary>delete entry</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="Entry">name of entry in section</param>
        /// <returns>true if entry was found and deleted</returns>
        public bool DeleteValue(string section, string entry)
        {
          var res = from en in (from sec in config.Elements() where sec.Attribute("name").Value == section select sec).Elements(entry) select en;
          if (res.Count() != 1) return false;
          res.First().Remove();
          return true;
        }
    
        /// <summary>read entry from section (! case sensitive)</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="entry">name of entry in section</param>
        /// <returns>value of entry in section</returns>
        public string GetValue(string section, string entry)
        {
          var res = from en in (from sec in config.Elements() where sec.Attribute("name").Value == section select sec).Elements(entry) select en;
          if (res.Count() != 1) return string.Empty;
          return res.First().Attribute("value").Value;
        }
    
        /// <summary>set value of entry in section. 
        /// if entry (and section) not exists, entry (and section) are added.</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="Entry">name of entry in section</param>
        /// <param name="Value">value of entry in sections</param>
        /// <param name="comment">true - comment netry, false - uncomment entry</param>
        /// <returns>true if sucsessvully set</returns>
        public bool SetValue(string section, string entry, string value, bool comment = false)
        {
          XElement xeSection;
          var resSection = from sec in config.Elements() where sec.Attribute("name") != null && sec.Attribute("name").Value == section select sec;
          if (resSection.Count() > 1) return false;
          if (resSection.Count() == 0)
          {
            xeSection = new XElement("section");
            xeSection.Add(new XAttribute("name", section));
            config.Add(xeSection);
          }
          else
          {
            xeSection = resSection.First();
          }
          XElement xeEntry;
          var resEntry = from en in xeSection.Elements(entry) where en.Attribute("value").Value == value select en;
          if (resEntry.Count() > 1) return false;
          if (resEntry.Count() == 0)
          {
            xeEntry = new XElement(entry);
            xeEntry.Add(new XAttribute("value", value));
            xeSection.Add(xeEntry);
          }
          else
          {
            xeEntry = resEntry.First();
            xeEntry.Attribute("value").Value = value;
          }
          // comment attribute
          XAttribute xaComment = xeEntry.Attribute("comment");
          if (xaComment == null)
          {
            xaComment = new XAttribute("comment", "");
            xeEntry.Add(xaComment);
          }
          xaComment.Value = comment.ToString();
          return true;
        }
    
        /// <summary>read all entries (without comments) and values</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <returns>Dictionary with entry name (Key) and value</returns>
        public Dictionary<String, String> GetSection(string section)
        {
          var res = from sec in config.Elements() where sec.Attribute("name").Value == section select sec;
          return (from en in res.Elements()
                  where en.Name != "comment"
                  select new { n = en.Name.ToString(), v = en.Attribute("value").Value })
                  .ToDictionary(a => a.n, a => a.v);
        }
    
        /// <summary>get all section names</summary>
        /// <returns>list of section names</returns>
        public List<String> GetAllSections() =>
          (from sec in config.Elements() where sec.Name != "comment" select sec.Attribute("@name").Value).ToList();
    
        private void LoadIniToXML()
        {
          XElement section = config;
          using (StreamReader sr = new StreamReader(this.FileName))
          {
            while (!sr.EndOfStream)
            {
              string line = sr.ReadLine().Trim();
              if (string.IsNullOrEmpty(line)) break;
              Match mEntry = regEntry.Match(line);
              Match mSection = regCaption.Match(line);
              Match mComment = regComment.Match(line);
              if (mSection.Success)
              {
                section = new XElement("section");
                section.Add(new XAttribute("name", mSection.Groups["section"].Value.Trim()));
                config.Add(section);
              }
              else if (mEntry.Success)
              {
                XElement xe;
                if (CommentCharacters.Contains(mEntry.Groups["entry"].Value[0]))
                {
                  xe = new XElement(mEntry.Groups["entry"].Value.Trim().Substring(1));
                  xe.Add(new XAttribute("comment", "True"));
                }
                else xe = new XElement(mEntry.Groups["entry"].Value.Trim());
                xe.Add(new XAttribute("value", mEntry.Groups["value"].Value.Trim()));
                section.Add(xe);
              }
              else if (mComment.Success)
              {
                XElement xe = new XElement("comment");
                xe.Value = mComment.Groups["comment"].Value.Trim();
                section.Add(xe);
              }
            }
          }
        }
    
        private void SaveXMLToIni()
        {
          using (StreamWriter sw = new StreamWriter(this.FileName))
          {
            foreach (var item in config.Descendants())
            {
              switch (item.Name.ToString())
              {
                case "section":
                  sw.WriteLine($"[{item.Attribute("name").Value}]");
                  break;
                case "comment":
                  sw.WriteLine((item.Value.Length == 0) ? string.Empty : CommentCharacters[0] + item.Value);
                  break;
                default:
                  if (item.Attribute("comment") != null && item.Attribute("comment").Value == "True") sw.Write(CommentCharacters[0]);
                  sw.WriteLine($"{item.Name}={item.Attribute("value").Value}");
                  break;
              }
            }
          }
        }
    
    
        /// <summary>export alle sections, entry, comments as XML</summary>
        /// <returns>XML document</returns>
        public XElement ExportToXElement() => config;
      }
    }
    

2 additional answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2020-09-26T09:03:00.807+00:00

    Hi,
    to read, change and write ini file you can use following class:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text.RegularExpressions;
    using System.Xml.Linq;
    
    namespace ListTxt
    {
      /// <summary>class for ini files</summary> 
      public class ConfigClass
      {
    
        #region Fields
        /// <summary>content of ini in xml</summary>
        private XElement config = new XElement("config");
    
        /// <summary>char for identification of comment, first char is default</summary>
        private string CommentCharacters = "#";
    
        /// <summary>regex to identify comment</summary>
        private string regCommentStr = "";
        private Regex regComment;
    
        /// <summary>reges to identiy element</summary>
        private Regex regEntry;
    
        /// <summary>regex to identiy header</summary>
        private Regex regCaption;
    
        #endregion
    
        #region constructors
    
        /// <summary>empty constructor</summary>
        public ConfigClass()
        {
          regCommentStr = @"(\s*[" + CommentCharacters + "](?<comment>.*))?";
          regComment = new Regex(regCommentStr);
          regEntry = new Regex(@"^[ \t]*(?<entry>([^=])+)=(?<value>([^=" + CommentCharacters + "])+)" + regCommentStr + "$");
          regCaption = new Regex(@"^[ \t]*(\[(?<section>([^\]])+)\]){1}" + regCommentStr + "$");
        }
    
        /// <summary>constructor to read ini file</summary>
        /// <param name="filename">name fo inifile</param>
        public ConfigClass(string fileName) : base()
        {
          if (!File.Exists(fileName)) throw new IOException($"File {fileName}  not found");
          this.FileName = fileName;
          LoadIniToXML();
        }
    
        #endregion
    
        /// <summary>save ini file</summary>
        /// <returns></returns>
        public bool Save()
        {
          if (string.IsNullOrEmpty(this.FileName)) return false;
          try { SaveXMLToIni(); }
          catch (Exception ex) { throw new IOException($"error writing ini file {this.FileName}", ex); }
          return true;
        }
    
        /// <summary>full file name</summary>
        public string FileName { get; set; }
    
        /// <summary>directory of file</summary>
        public string Directory
        {
          get
          {
            if (System.IO.Directory.Exists(this.FileName)) return Path.GetDirectoryName(this.FileName);
            return string.Empty;
          }
        }
    
    
        /// <summary>comment entry</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="entry">name of entry in section</param>
        /// <returns>true if entry was found in section</returns>
        public bool CommentValue(string section, string entry)
        {
          var res = from en in (from sec in config.Elements() where sec.Attribute("name").Value == section select sec).Elements(entry) select en;
          if (res.Count() != 1) return false;
          res.First().Value = CommentCharacters + res.First().Name.ToString() + "=" + res.First().Attribute("name").Value;
          res.First().Name = "comment";
          return true;
        }
    
        /// <summary>delete entry</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="Entry">name of entry in section</param>
        /// <returns>true if entry was found and deleted</returns>
        public bool DeleteValue(string section, string entry)
        {
          var res = from en in (from sec in config.Elements() where sec.Attribute("name").Value == section select sec).Elements(entry) select en;
          if (res.Count() != 1) return false;
          res.First().Remove();
          return true;
        }
    
        /// <summary>read entry from section (! case sensitive)</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="entry">name of entry in section</param>
        /// <returns>value of entry in section</returns>
        public string GetValue(string section, string entry)
        {
          var res = from en in (from sec in config.Elements() where sec.Attribute("name").Value == section select sec).Elements(entry) select en;
          if (res.Count() != 1) return string.Empty;
          return res.First().Attribute("value").Value;
        }
    
        /// <summary>set value of entry in section. 
        /// if entry (and section) not exists, entry (and section) are added.</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <param name="Entry">name of entry in section</param>
        /// <param name="Value">value of entry in sections</param>
        /// <returns>true if sucsessvully set</returns>
        public bool SetValue(string section, string entry, string value)
        {
          XElement xeSection;
          var resSection = from sec in config.Elements() where sec.Attribute("name").Value == section select sec;
          if (resSection.Count() > 1) return false;
          if (resSection.Count() == 0)
          {
            xeSection = new XElement("section");
            xeSection.Add(new XAttribute("name", section));
            config.Add(xeSection);
          }
          else
          {
            xeSection = resSection.First();
          }
          var resEntry = from en in xeSection.Elements(entry) select en;
          if (resEntry.Count() > 1) return false;
          if (resEntry.Count() == 0)
          {
            XElement xeEntry = new XElement(entry);
            xeEntry.Add(new XAttribute("value", value));
            xeSection.Add(xeEntry);
          }
          else
          {
            xeSection.Attribute("value").Value = value;
          }
          // extend method, if you want uncommen commented entry 
          return true;
        }
    
        /// <summary>read all entries (without comments) and values</summary>
        /// <param name="section">name of section (in [...])</param>
        /// <returns>Dictionary with entry name (Key) and value</returns>
        public Dictionary<String, String> GetSection(string section)
        {
          var res = from sec in config.Elements() where sec.Attribute("name").Value == section select sec;
          return (from en in res.Elements()
                  where en.Name != "comment"
                  select new { n = en.Name.ToString(), v = en.Attribute("value").Value })
                  .ToDictionary(a => a.n, a => a.v);
        }
    
        /// <summary>get all section names</summary>
        /// <returns>list of section names</returns>
        public List<String> GetAllSections() =>
          (from sec in config.Elements() where sec.Name != "comment" select sec.Attribute("@name").Value).ToList();
    
        private void LoadIniToXML()
        {
          XElement section = config;
          using (StreamReader sr = new StreamReader(this.FileName))
          {
            while (!sr.EndOfStream)
            {
              string line = sr.ReadLine().Trim();
              Match mEntry = regEntry.Match(line);
              Match mSection = regCaption.Match(line);
              Match mComment = regComment.Match(line);
              if (mSection.Success)
              {
                section = new XElement("section");
                section.Add(new XAttribute("name", mSection.Groups["section"].Value.Trim()));
                config.Add(section);
              }
              else if (mEntry.Success)
              {
                XElement xe = new XElement(mEntry.Groups["entry"].Value.Trim());
                xe.Add(new XAttribute("value", mEntry.Groups["value"].Value.Trim()));
                section.Add(xe);
              }
              else if (mComment.Success)
              {
                XElement xe = new XElement("comment");
                xe.Value = mComment.Groups["comment"].Value.Trim();
                section.Add(xe);
              }
            }
          }
        }
    
        private void SaveXMLToIni()
        {
          using (StreamWriter sw = new StreamWriter(this.FileName))
          {
            foreach (var item in config.Descendants())
            {
              switch (item.Name.ToString())
              {
                case "section":
                  sw.WriteLine($"[{item.Attribute("name")}]");
                  break;
                case "comment":
                  sw.WriteLine((item.Value.Length == 0) ? string.Empty : CommentCharacters[0] + item.Value);
                  break;
                default:
                  sw.WriteLine($"{item.Name}={item.Attribute("value").Value}");
                  break;
              }
            }
          }
        }
    
    
      /// <summary>export alle sections, entry, comments as XML</summary>
        /// <returns>XML document</returns>
        public XElement ExportToXElement() => config;
      }
    }
    

  2. jack pelon 96 Reputation points
    2020-10-16T03:29:35.897+00:00

    Hello, I have been doing tests, but since I am a novice in programming, I have not managed to reach my goal. It might be possible that by clicking the "save" button, the names selected in the listbox can be saved in the * .ini file that you select in the "Textbox". Please I hope I can count on your help. I send a cordial greeting.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.