С# сохранение цветов многих вещей

Мне удалось получить на ходу средство выбора цвета, которое работает, но я хочу иметь возможность сохранять цвета, которые хочет пользователь. Я сделал ссылки на цветной диалог для меток/выпадающих списков/других элементов управления как отдельные элементы, которые работают, но я хотел бы знать, как их сохранить (возможно, в файл txt или что-то еще), поскольку при перезапуске программы он снова становится черным и белый.

Дело в том, что это не просто 1 или 2 изменения цвета, у меня есть 35 меток, 7 выпадающих списков, 4 радиокнопки, 5 вкладок, 22 текстовых поля (текст и фон каждого), 10 кнопок (текст и фон каждого) и МНОГО numericupdowns (текст и фон каждого) - я только что провел последний час, сортируя каждый с помощью палитры цветов ... Я не хочу делать что-то с каждым по очереди, если я могу помочь... Есть ли способ, или мне придется пройти их все :)


person Sean    schedule 15.07.2015    source источник
comment
Текстовый формат, подобный этому label1=255*0*0 CRLF comboBox1=0*255*225, одна строка для каждого имени элемента управления (за которым следует RGB) ?   -  person Graffito    schedule 15.07.2015


Ответы (3)


Я бы следил за процессом сохранения цветов при закрытии формы, загрузки цветов при загрузке формы, а затем применения цветов по умолчанию после их загрузки. Я сохраняю настройки в глобальной переменной внутри формы, поэтому я могу ссылаться на них по имени. Переменная настроек:

 public Dictionary<string, FieldColor> colorSettings = new Dictionary<string, FieldColor>();

Я использую следующую структуру, потому что в настоящее время у вас есть два цвета, но вы можете добавить больше свойств, если возникнет необходимость. Структура данных:

 public struct FieldColor
{
    public Color BackColor;
    public Color ForeColor;
    public FieldColor(Color backColor, Color foreColor)
    {
        this.BackColor = backColor;
        this.ForeColor = foreColor;
    }
}

Метод сохранения выполняет итерацию по каждому элементу управления, затем выполняет итерацию по его дочерним элементам управления, и, если цвет не является цветом формы по умолчанию, он сохраняет строку. Это сохраняет его как csv. Сохранять:

public void SaveFieldColors(Control parent, StreamWriter colorWriter)
    {
        foreach (Control currentControl in parent.Controls)
        {
            if (currentControl.ForeColor != DefaultForeColor || currentControl.BackColor != DefaultBackColor)
            {
                //Save the file in your format
                colorWriter.WriteLine(currentControl.Name + "," + currentControl.BackColor.ToArgb() + "," + currentControl.ForeColor.ToArgb());
            }
            ApplyDefaultColorToControls(currentControl);
        }
    }

Чтобы загрузить настройки, я просто разбиваю каждую строку на запись в словаре colorSettings. Нагрузка:

 public void LoadFieldColors(StreamReader colorReader)
    {
        while (colorReader.EndOfStream == false)
        {
            //Read the file from your format
            string line = colorReader.ReadLine();
            string[] fieldData = line.Split(',');
            colorSettings.Add(fieldData[0], new FieldColor(Color.FromArgb(int.Parse(fieldData[1])), Color.FromArgb(int.Parse(fieldData[2]))));
        }
    }

Здесь я перебираю каждый элемент управления и его дочерние элементы, чтобы применить форматирование, если есть запись для имени этого элемента управления. Если его нет, я просто устанавливаю его по умолчанию. Примените форматирование:

        public void ApplyDefaultColorToControls(Control parent)
        {
            foreach (Control currentControl in parent.Controls)
            {
               if (colorSettings.ContainsKey(currentControl.Name) == true)
               {
                //Set the controls settings equal to their color in your stored dictionary
                currentControl.BackColor = colorSettings[currentControl.Name].BackColor;
                currentControl.ForeColor = colorSettings[currentControl.Name].ForeColor;
               }
               else
               {
                //Set the control settings equal to default settings
                currentControl.BackColor = DefaultBackColor;
                currentControl.ForeColor = DefaultForeColor;
               }
            ApplyDefaultColorToControls(currentControl);
        }
    }

Пример вызовов из событий формы:

private void Form1_Load(object sender, EventArgs e)
    {
        using (StreamReader settingsReader = new StreamReader(@"C:\path\to\file\filename.ending"))
        {
            LoadFieldColors(settingsReader);
        }
        ApplyDefaultColorToControls(this);
    }
           private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        using (StreamWriter settingsWriter = new StreamWriter(@"C:\path\to\file\filename.ending"))
        {
            SaveFieldColors(this, settingsWriter);
        }
    }
}
person lamorach    schedule 15.07.2015
comment
Привет - это форма окна. Я полагаю, я должен сказать, что я нуб, когда дело доходит до такого рода вещей, и большинство комментариев полностью потеряны для меня, лол. - person Sean; 16.07.2015
comment
Обновил его, используя пример Windows Forms. - person lamorach; 16.07.2015
comment
Мне нужно хорошенько взглянуть на это завтра ... немного сложно для этого времени ночи, ха-ха. Спасибо - person Sean; 17.07.2015
comment
Я не был уверен, какой информации будет слишком много или слишком мало, поэтому я пошел в сторону избытка. - person lamorach; 17.07.2015
comment
Что ж, ваши усилия высоко ценятся. Я поместил ваш код в свой проект, но он по-прежнему не сохраняет цвета... Я поставил @"C:/BMW/Colours.txt" там, где вы сказали указать имя файла. Или он должен быть в определенном формате... Я знаю, что вы упомянули CSV ранее в своем посте? - person Sean; 18.07.2015

Есть много способов хранить данные в С#, начиная с простого текстового файла и заканчивая базами данных... это слишком широко. Как бы вы ни решили сохранить данные, я предлагаю начать с Dictonary<string, Touple<color, color>>, где строка — это имя элемента управления, один — это backColor, а другой — foreColor, и сериализовать его в файл (xml или json, все это не имеет значения) много).
При загрузке формы используйте рекурсивную функцию для this.Controls, чтобы изменить цвета для каждого элемента управления.

person Zohar Peled    schedule 15.07.2015
comment
Также прочитайте это. - person Zohar Peled; 16.07.2015
comment
Спасибо за это. Сегодня мне удалось заставить цвета записать в текстовый файл Colours.txt. Он пишет это как Text Color [Blue] (для текста), затем следующая строка предназначена для фона и пишет его таким же образом. Теперь мне просто нужен способ получить их в программе при запуске... - person Sean; 16.07.2015

Вы можете попробовать это, если это для проекта WinForms. Создайте класс для своих настроек:

[Serializable]
sealed class Settings
{
    internal Dictionary<string, Color> ForeColors { get; set; }
    internal Dictionary<string, Color> BackColors { get; set; }

    internal Settings()
    {
        ForeColors = new Dictionary<string, Color>();
        BackColors = new Dictionary<string, Color>();
    }

    internal void Save(string fileName = @"settings.ini")
    {
        using (FileStream stream = File.Create(Directory.GetCurrentDirectory() + "\\" + fileName))
        {
            BinaryFormatter serializer = new BinaryFormatter();
            serializer.Serialize(stream, this);
        }
    }

    internal static Settings Load(string fileName = @"settings.ini")
    {
        if (!File.Exists(Directory.GetCurrentDirectory() + "\\" + fileName)) return null;
        using (FileStream stream = File.OpenRead(Directory.GetCurrentDirectory() + "\\" + fileName))
        {
            BinaryFormatter serializer = new BinaryFormatter();
            return serializer.Deserialize(stream) as Settings;
        }
    }
}

Теперь в форме Windows подпишитесь на события Form_Load Form_Closing и добавьте обработчики:

    private void Form1_Load(object sender, EventArgs e)
    {            
        Settings s = Settings.Load();
        if (s == null) return;
        foreach (Control item in this.Controls)
        {
            item.ForeColor = s.ForeColors[item.Name];
            item.BackColor = s.BackColors[item.Name];
        }
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        Settings s = new Settings();
        foreach (Control item in this.Controls)
        {
            s.ForeColors.Add(item.Name, item.ForeColor);
            s.BackColors.Add(item.Name, item.BackColor);
        }
        s.Save();
    }
person Fabjan    schedule 15.07.2015
comment
Хорошо, хотя я бы создал структуру, чтобы сохранить параметры стиля (ForeColor, BackColor) и иметь внутри метод, который получает управление и применяет стиль. (см. мой ответ на аналогичный вопрос некоторое время назад). Затем в классе настроек вам нужно сохранить только один словарь, а конечно, вы можете добавить метод ApplySettings к объекту настроек, который будет перебирать элементы управления внутри. - person Zohar Peled; 16.07.2015
comment
@ZoharPeled Я просто хотел показать основную идею, но не наилучшую реализацию. - person Fabjan; 16.07.2015
comment
Я не уверен, что мое предложение является наилучшей возможной реализацией ... Я просто предложил то, что, по моему мнению, является улучшением вашего ответа, примите его или оставьте, это зависит от вас и ОП ... - person Zohar Peled; 16.07.2015
comment
@ZoharPeled //метод, который получает элемент управления (объект) и применяет стиль// эта идея тоже пришла мне в голову, но мне не нравится тот факт, что мы передаем объект управления в качестве параметра некоторому экземпляру структуры (или класса). Имхо это не очень хорошая вещь. Лучше, когда только форма окна может работать с элементами управления формы окна. - person Fabjan; 16.07.2015
comment
Это правильное замечание, но тогда вам придется написать логику применения темы в базовой форме или в любой другой форме вашего приложения. возможно, было бы лучше добавить метод расширения в форму. - person Zohar Peled; 16.07.2015
comment
Если конфигурация должна быть разделена между разными пользователями, в основном в случае приложений, расположенных на сетевом диске, класс Settings не является подходящим решением: конфигурация должна храниться в сетевом файле. - person Graffito; 16.07.2015
comment
Спасибо за ответы. Я пытался использовать это, но он не сохраняет файл settings.ini и, следовательно, не сохраняет цвета. Нужно ли что-то вставлять в кнопку? - person Sean; 18.07.2015