Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
1

Редактирование файла с использованием checkbox

07.02.2017, 20:02. Показов 972. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток.
Подскажите пожалуйста как подойти к решению такой задачи:

Есть три сущности:
- Программа "А"
- Приложение "В"
- Файл питоновский "test.py"

1) test.py является по сути перечнем настроек, которые программа "А" из него считывает при запуске. Настроек много и они разбиты на 10 отдела (для визуального удобства), в каждом из которых около 10 -20 настроек.

2) Программ "А" несколько и все они лежат в разных папках, со своими test.py.

3) Приложение "В" одно, содержит в себе TabControl, вкладки которого являются теми самыми файлами test.py. В каждом таком TabControl есть еще один TabControl с 10 вкладками, которые являются отделами настроек test.py. И в каждом этом отделе уже чекбоксы, которые отвечают за вкл/выкл определённой настройки в этом файле. Снизу кнопка "Принять", перезаписывающая test.py в зависимости от выставленных чекбоксами настройками. Перезапись нужно сделать именно поиском нужно строки и перезаписью её значения, потому как в файл периодически добавляется новый функционал и нужна быстрая поддержка.
*Создание формы с путями ко всем файлам есть. Не хватает именно понимания как отредактировать файл с помощью чекбоксов.

Настройки в файле выглядят примерно так:
Python
1
2
3
4
5
6
#otdel_1
_firstParam     = False # описание функции
_secondParam    = False # описание функции
#otdel_2
_thirdParam     = False # описание функции
_fourthParam    = False # описание функции
(пробелов между названием функции и знаком равенства может быть разное кол-во)

У меня есть какие-то части данного функционала, но я уже сейчас понимаю, что эту задачу нужно решать изначально как единый механизм, до которого я не могу дойти из-за своего малого опыта. Поэтому не имеет смысла выкладывать что есть, потому как этим запросто можно пренебречь, если будет единое решение. Был бы очень благодарен за любую помощь в решении.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.02.2017, 20:02
Ответы с готовыми решениями:

Создание и редактирование cmd-файла с использованием bat-файла
Нужно создать cmd файл в %systemroot% и отредактировать его из bat'ника

CheckBox и редактирование в бд
Приветствую всех! <!Doctype html> <html> <head></head> <body> <section class="wrapper"> ...

CheckBox редактирование файлов в бд
Приветствую всех дорогие форумчане! Вот вывел я список из бд в таблицу html. у каждой строки в...

Вывод, редактирование и удаление полей из таблицы в checkbox
Всем Здравствуйте! Столкнулся с такой проблемой( Имеется База данных "Viz", в ней имеется таблица...

15
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
07.02.2017, 20:54 2
Insearchman, имена параметров уникальны в рамках одного файла? Вкладки с названиями отделов фиксированы или должны создаваться на лету исходя из наличия отделов в .py файле? Если нужно создание на лету, то каким образом делить параметры на отделы? Чекбоксы во вкладках фиксированы или должны создаваться на лету исходя их содержимого файла? Могут ли в файле встречаться закоментированные настройки и что должна делать программа с ними?
1
61 / 50 / 1
Регистрация: 09.07.2009
Сообщений: 451
07.02.2017, 21:04 3
Читаются параметры с их значениями примерно так:
C#
1
2
3
4
5
6
7
8
9
            //Считанная строка из файла
            string s = "_firstParam     = False";
            //Разбиваем строку по знаку '=', получаем массив из двух строк
            string[] str = s.Split('=');
            //Название параметра - нулевая строка массива с удаленными проблемами слева и справа 
            string param1 = str[0].Trim();
            //Значение параметра - первая строка массива с удаленными проблемами слева и справа,
            //преобразованное к типу bool
            bool value1 = Convert.ToBoolean(str[1].Trim());
Имена параметров скорее всего уникальны. А то тогда было бы не понятно к какой настройке что относится.

Проверяем чекбокс, ищем в файле нужный параметр и заменяем.
C#
1
2
3
4
            if (checkBoxParam1.Checked)
            { 
                //Ищем нужную строку с параметром и заменяем его
            }
Возможно, удобнее все строки файла сразу в массив считать.

Ну это как предложения. Возможно, найдутся и более удобные решения.
1
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
07.02.2017, 21:08  [ТС] 4
В рамках одного файла имена уникальные, да. Вкладки с названиями отделов созданы как и чекбоксы фиксированные. На лету конечно было бы хорошо сделать, но на самом деле нет уверенности что данный файл в последствии не будет радикально реарганизован. Поэтому всё сделал фиксированным с прописанными именами. Закоментированные настройки трогать не нужно, как и отображать. Вначале хотя бы вручную всё сделать.
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
08.02.2017, 19:48 5
Insearchman, тогда я предлагаю следующую систему:

1) для закладок первого tabControl в Tag записываем полный путь к файлу (через дизайнер или в конструкторе формы)

2) для каждого checkbox в Tag записываем название настройки. Вместо этого можно указать название настройки в имени элемента управления. Чтобы не было конфликта между одноименными настройки в разных файлах, то можно взять следующую схему именования - cb_имяФайла_имяНастройки.

3) В событии Load делаем цикл по всем закладкам первого tabControl. На каждой итерации читаем файл (имя его хранится в Tag у TabPage). Читаем файл целиком в память (File.ReadAllLines). Далее получаем список всех checkbox (см. AllControlsOfType() ниже) и заносим в Dictionary<string,CheckBox> где ключом является имя настройки. Пробегаемся по всем строкам файла, получаем имя параметра и значение параметра (проще с помощью регулярок), если параметр закоментирован (начинается с #), то скрываем соответствущий checkbox. Иначе ставим иди убираем его отметку исходя из значения (True или False) параметра.

4) Всем кнопкам "принять" назначаем одинаковый обработчик события click. В этом обработчике мы получаем tabPage в котором находится эта кнопка (чтобы получить имя файла). Далее читаем весь файл в память, получаем все видимые checkbox-ы из таба и делаем Replace значения с помощью регулярного выражения (имя параметра получаем из Tag или имени чекбокса). В конце сохраняем файл.

Как-то так ...

Добавлено через 21 час 33 минуты
Забыл привести код функции AllControlsOfType и FindParent которые могут оказаться полезными для решения задачи
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
static class MyExtensions
{
    public static IEnumerable<Control> AllControls(this Control parentControl)
    {
        foreach (Control ctrl in parentControl.Controls)
        {
            yield return ctrl;
            foreach (Control childCtrl in ctrl.AllControls())
            {
                yield return childCtrl;
            }
        }
    }
 
    public static IEnumerable<TControl> AllControlsOfType<TControl>(this Control parentControl) where TControl : Control
    {
        foreach (Control ctrl in parentControl.Controls)
        {
            TControl result = ctrl as TControl;
            if (result != null) yield return result;
 
            foreach (TControl childCtrl in ctrl.AllControlsOfType<TControl>())
            {
                yield return childCtrl;
            }
        }
    }
 
    public static TControl FindParent<TControl>(this Control ctrl) where TControl : Control
    {
        if (ctrl == null) return null;
        for (;;)
        {
            Control parent = ctrl.Parent;
            if (parent == null || parent is TControl) return (TControl)parent;
            ctrl = parent;
        }
    }
}
1
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
08.02.2017, 21:33  [ТС] 6
Большое спасибо за ответы! Очень помогли понять что делать дальше.
На основании ваших ответов я смог составить следующий набор функций, необходимых для реализации моей задачи:

1) Написать функцию "GetFunction()", создающую массив "_functions[name]" из считанных имён всех чекбоксов*
2) Написать функцию "GetStatus()", создающую двумерный массив "_status[name, status]" из названий функций (путём поиска строк из массива "_functions[name]" в файле test.py) и текущего её значения. А также, выставлением чекбоксов на основании полученных значений статуса каждой функции.
3) Написать метод в каждом чекбоксе, изменяющий значение статуса каждой функции в массиве "_status[name, status]" в зависимости от вкл./выкл. соответствующего чекбокса.
4) Написать функцию "SetStatus()", заменяющую текущее значение статусов функций в файле, значением из массива "_status[name, status]"


Буду благодарен если вы меня поправите в плане задач, а так же подскажете как это сделать.
Времени на программирование у меня час-полтора после работы, поэтому любая помощь была бы крайне кстати)

*Имена чекбоксов совпадают с именами функций. При таком подходе если и появится какая-нибудь новая функция, мне достаточно будет добавить чекбокс с её именем.
0
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
21.02.2017, 21:13  [ТС] 7
Цитата Сообщение от Лакшми Посмотреть сообщение
Читаются параметры с их значениями примерно так:
Спасибо, очень помогли!
Цитата Сообщение от Лакшми Посмотреть сообщение
bool value1 = Convert.ToBoolean(str[1].Trim());
А как удалить комменты вместе со знаком #, которые идут в первой строке массива после него?
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
21.02.2017, 21:17 8
Insearchman,
C#
1
2
3
string s = "Текст где может быть # комментарий";
int hashIdx = s.IndexOf('#');
if (hashIdx != -1) s = s.Substring(0, hashIdx);
1
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
01.03.2017, 13:26  [ТС] 9
Цитата Сообщение от OwenGlendower Посмотреть сообщение
C#
1
2
3
string s = "Текст где может быть # комментарий";
int hashIdx = s.IndexOf('#');
if (hashIdx != -1) s = s.Substring(0, hashIdx);
Спасибо, очень помогло. Правда теперь другая проблема, я не совсем понимаю как работать со строкой. Мне нужно заменить путь в строке вида:
C#
1
  wcroot = %q["J:\Test\test"]
Я думаю воспользоваться вот этим методом:
Цитата Сообщение от Лакшми Посмотреть сообщение
C#
1
string[] str = s.Split('=');
разбивая на части от ковычек, заменяя, а потом склеивая строчку. Подскажите правильно ли я иду или есть способ проще?
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
01.03.2017, 13:35 10
Insearchman, это правильный способ
1
61 / 50 / 1
Регистрация: 09.07.2009
Сообщений: 451
01.03.2017, 13:53 11
Конкретно по Вашему примеру получится массив из трех элементов. Вам нужен второй, а точнее str[1].
C#
1
string[] str = wcroot.Split('"');
1
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
01.03.2017, 18:04  [ТС] 12
Цитата Сообщение от Лакшми Посмотреть сообщение
Конкретно по Вашему примеру получится массив из трех элементов. Вам нужен второй, а точнее str[1].
Спасибо за уточнение. И еще тогда вопрос - можно ли в массиве, созданного из строк прочитанного файла, вставить новую строку (элемент массива) в середине оного?
0
61 / 50 / 1
Регистрация: 09.07.2009
Сообщений: 451
01.03.2017, 20:02 13
Массив имеет фиксированную длину, поэтому напрямую вставить элемент в массив строк не получится. Можно извращаться по-разному, например, создать еще один массив на 1 символ длиннее, скопировать в него элементы ДО вставляемого элемента, потом сам элемент, а за ним оставшуюся часть массива. Но как по мне, так это полнейший изврат. Лично я использовала бы List, это очень удобная штука, имеет массу разных функций для манипулирования элементами. https://msdn.microsoft.com/ru-... .110).aspx
Пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
            //Создадим массив строк для примера
            string[] arrStr = new string[5];
 
            arrStr[0] = "Строка 1";
            arrStr[1] = "Строка 2";
            arrStr[2] = "Строка 3";
            arrStr[3] = "Строка 4";
            arrStr[4] = "Строка 5";
 
            //Преобразуем массив в List
            List<string> listStr = arrStr.ToList<string>();
 
            //Вставляем нужный элемент в позицию 2
            listStr.Insert(2, "Вставленная строка");
Вот что получим:
Миниатюры
Редактирование файла с использованием checkbox  
1
0 / 0 / 0
Регистрация: 24.01.2017
Сообщений: 25
02.03.2017, 11:59  [ТС] 14
Цитата Сообщение от Лакшми Посмотреть сообщение
это очень удобная штука, имеет массу разных функций для манипулирования элементами.
Да, полностью согласен, но у меня с листом как-то с самого начала не заладилось. Видимо в силу моего малого опыта.
А именно, File.ReadAllLines не работает с листом, также при преобразовании массива в лист пишет о что инициализатор поля не может обращаться к не статичному (а мне нужно его изменять и потом записывать обратно в файл). Это можно как-то решить?
Цитата Сообщение от OwenGlendower Посмотреть сообщение
int hashIdx = s.IndexOf('#');
Подскажите пожалуйста, а как убрать знак \ из строки? Если писать его в "" - происходит какая-то отмена следующего знака (даже в этой форме форума я не могу его написать) или что-то вроде того. Мне это нужно в проверке что если в строке первый знак \ тогда его нужно удалить.
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
02.03.2017, 12:32 15
Цитата Сообщение от Insearchman Посмотреть сообщение
File.ReadAllLines не работает с листом
Массив можно превратить в список
C#
1
List<string> lines = new List<string>(File.ReadAllLines(@"c:\file.txt"));
Цитата Сообщение от Insearchman Посмотреть сообщение
также при преобразовании массива в лист пишет о что инициализатор поля не может обращаться к не статичному. (а мне нужно его изменять и потом записывать обратно в файл). Это можно как-то решить?
Это не имеет отношения к List<T>. Решить это можно если ты покажешь код где возникает ошибка.

Цитата Сообщение от Insearchman Посмотреть сообщение
Мне это нужно в проверке что если в строке первый знак \ тогда его нужно удалить.
C#
1
2
3
4
5
6
7
string s;
 
// Способ №1
if (s.StartsWith("\\")) s = s.Substring(1);
 
// Способ №2
s = s.TrimStart('\');
1
61 / 50 / 1
Регистрация: 09.07.2009
Сообщений: 451
02.03.2017, 12:41 16
C#
1
2
3
4
string[] s = File.ReadAllLines("1.txt"); 
List<string> list = s.ToList<string>();
list.Insert(2, "new string"); 
s = list.ToArray();
По поводу слеша - пишите два подряд, так слеш поймется.
1
02.03.2017, 12:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.03.2017, 12:41
Помогаю со студенческими работами здесь

Поиск с использованием Checkbox
У меня есть таблица с городами и улицами, города я вывожу в месте с чекбоксом 1-Париж 2-Лион 3-и...

Поиск с использованием checkbox
Доброй ночи столкнулся с такой проблемой Делаю поиск по параметрам в качестве выбора параметра...

Задачка с использованием CheckBox
Добрый день.Вопрос много,могут показаться глупыми)) Мне нужно в зависимости от выбранных...

Папка с использованием CheckBox
Здравствуйте! Есть отрывок из программы. procedure TForm1.Button1Click(Sender: TObject); begin...

Автофильтр в эксель с использованием checkbox
доброе время суток! решил облегчить условия труда и в итоге попал в тупик из за слабых знаний VB B...

Фильтрация с использованием ComboBox и CheckBox.
Помогите сделать фильтрацию с использованием ComboBox и CheckBox - Delphi БД


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru