Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
5 / 5 / 3
Регистрация: 07.04.2011
Сообщений: 58

Сериализация кнопок для использования в других приложениях

11.01.2012, 21:37. Показов 2188. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток уважаемые форумчане!

Перейду сразу к делу. Решил написать программу (по идее не сложную) Имеется скажем 10 кнопок, которые предусмотрены для запуска других приложений (Skype, winamp ...)
События каждой кнопки одинаковые: (кроме нумерации prog1, prog2, ...)

C#
1
2
3
4
5
6
7
        private void button1_Click_1(object sender, EventArgs e)
        {
            Process prog1 = new Process();
            prog1.StartInfo.FileName = @"";
            prog1.StartInfo.Arguments = "";
            prog1.Start();
        }
Решил я всё это дело сериализовать, что-бы после перезвпуска приложения все события кнопок сохранялись.

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
40
41
42
43
44
45
46
47
public class PropsFields
    {
        public string XMLFileName = Environment.CurrentDirectory + "\\settings.xml";
        public string prog1_name = @"";
        public string prog1_path = @"";
        public string prog1_param = @"";
        public string prog2_name = @"";
        public string prog2_path = @"";
        public string prog2_param = @"";
        public string prog3_name = @"";
        public string prog3_path = @"";
        public string prog3_param = @"";
        public string prog4_name = @"";
        public string prog4_path = @"";
        public string prog4_param = @"";
        
...
...
 
    }
    public class Props
    {
        public PropsFields Fields;
        public Props()
        {
            Fields = new PropsFields();
        }
        public void WriteXml()
        {
            XmlSerializer ser = new XmlSerializer(typeof(PropsFields));
            TextWriter writer = new StreamWriter(Fields.XMLFileName);
            ser.Serialize(writer, Fields);
            writer.Close();
        }
        public void ReadXml()
        {
            if (File.Exists(Fields.XMLFileName))
            {
                XmlSerializer ser = new XmlSerializer(typeof(PropsFields));
                TextReader reader = new StreamReader(Fields.XMLFileName);
                Fields = ser.Deserialize(reader) as PropsFields;
                reader.Close();
            }
            else { }
        }
 
    }
Я задумал добавлять кнопки так:
При нажатии кнопки "Добавить кнопку" появляется форма с тремя TextBox в которые вписываем ( prog1_name, prog1_path, prog1_param) и одним CheckBox в котором выбираем для какой кнопки следует сохранить настройки.
Сериализовать события одной кнопки просто, а вот как быть с остальными 9 пока не могу разобраться.
Проблема в том что файл settings.xml каждый раз пересоздаёться а мне его нужно дописывать.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.01.2012, 21:37
Ответы с готовыми решениями:

XML стиль для кнопок и других элементов управления в WinForms
Написал прожку на формах. Теперь захотелось навести красивости. Знаю что разные красивости можно сделать в WPF, но переписывать прожку...

Создание модуля для использования его в других формах
Доброго времени суток, помогите создать модуль, где будет объявлено подключение к БД как Public. Хочу открыть подключение для двух форм,...

Как скомпилировать проект для использования приложения на других ПК
Всем посещаемым здрасте! Я создал проект на Microsoft Visual studio 2010 c# Windiws Form а как теперь его сохранить что он запускался...

14
5 / 5 / 3
Регистрация: 07.04.2011
Сообщений: 58
13.01.2012, 15:17  [ТС]
Может я зря написал это в разделе С# для начинающих?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
14.01.2012, 15:33
Так-то ничего сложного нету. Особенно, если всё же перезаписывать сериализовывая всю коллекцию, а не дописывать, удалять из xml. Сейчас, что-нибудь сваяю.

Добавлено через 12 минут
Класс хранящий те самые данные для запуска приложений:
ProcessProperties.cs
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
40
41
42
43
44
45
46
47
48
49
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
 
namespace ConsoleApplication1
{
    public class ProcessProperties
    {
        public ProcessProperties()
        {
        }
 
        public ProcessProperties(string name, string path, string arguments)
        {
            Name = name;
            Path = path;
            Arguments = arguments;
        }
 
        public string Name { get; set; }
        public string Path { get; set; }
        public string Arguments { get; set; }
 
        public static void Save(List<ProcessProperties> processProperties, String FileName)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<ProcessProperties>));
            using (FileStream fs = new FileStream(FileName, FileMode.OpenOrCreate))
            {
                using (StreamWriter streamWriter = new StreamWriter(fs))
                {
                    xmlSerializer.Serialize(streamWriter, processProperties);
                }
            }
        }
 
        public static List<ProcessProperties> Load(String FileName)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<ProcessProperties>));
            using (FileStream fs = new FileStream(FileName, FileMode.Open))
            {
                using (StreamReader streamReader = new StreamReader(fs))
                {
                    return (List<ProcessProperties>)xmlSerializer.Deserialize(streamReader);
                }
            }
        }
    }
}


Работа программы:
Program.cs
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
using System;
using System.Collections.Generic;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string saveFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "PropertyList.xml");
 
            List<ProcessProperties> procProps = new List<ProcessProperties>()
            {
                new ProcessProperties("Skype", "Путь к Skype", "Аргументы для Skype"),
                new ProcessProperties("QIP", "Путь к QIP", "Аргументы для QIP"),
                new ProcessProperties("ICQ", "Путь к ICQ", "Аргументы для ICQ"),
            };
 
            ProcessProperties.Save(procProps, saveFile);
 
            List<ProcessProperties> loadedProperties = ProcessProperties.Load(saveFile);
 
            foreach (ProcessProperties prop in loadedProperties)
                Console.WriteLine(string.Format("Имя: {0}\t Путь: {1}\t Аргументы: {2}", prop.Name, prop.Path, prop.Arguments));
 
            Console.ReadKey();
        }
    }
}


На рабочий стол сохраняю просто ради примера. Ты сохраняй лучше в:
C#
1
2
string saveFile = Path.Combine(Environment.GetFolderPath(
        Environment.SpecialFolder.ApplicationData), "Название твоего приложения", "PropertyList.xml");
Только не забывай при каждом запуске программы проверять, существует ли эта папка, если нет, то создать.
Короче вот:
AppFolders.cs (пространство имён и using'и сам добавишь)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    internal class AppFolders
    {
        /// <summary>Корневая папка для всех сохраняемых элементов программы</summary>
        public String MainData { get; private set; }
 
        /// <summary>
        /// Инициализирует пути к данным приложения
        /// </summary>
        /// <param name="rootDirectoryName">Название корневой папки для хранения данных приложения</param>
        public AppFolders(String rootDirectoryName)
        {
            MainData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), rootDirectoryName);
        }
 
        /// <summary>Проверить папки приложения на существование, если не существуют, то создать их</summary>
        public void CheckFolders()
        {
            if (!Directory.Exists(MainData))
                Directory.CreateDirectory(MainData);
        }
    }


Получившийся в результате сохранения файл:
Содержимое сохранённого файла
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfProcessProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ProcessProperties>
    <Name>Skype</Name>
    <Path>Путь к Skype</Path>
    <Arguments>Аргументы для Skype</Arguments>
  </ProcessProperties>
  <ProcessProperties>
    <Name>QIP</Name>
    <Path>Путь к QIP</Path>
    <Arguments>Аргументы для QIP</Arguments>
  </ProcessProperties>
  <ProcessProperties>
    <Name>ICQ</Name>
    <Path>Путь к ICQ</Path>
    <Arguments>Аргументы для ICQ</Arguments>
  </ProcessProperties>
</ArrayOfProcessProperties>


Добавлено через 7 минут
Если надо сохранять асинхронно (ну мало ли у тебя там будет ооооочень много приложений), то можно делать хотя бы так:
C#
1
2
3
4
            ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object unused)
                {
                    ProcessProperties.Save(procProps, saveFile);
                }));
Хотя это не самый лучший вариант, ведь надо как-то узнавать, когда закончилось сохранение. Короче всё равно в некоторых ситуациях вполне приемлем и этот способ. Самый простой способ узнавать, когда закончился сэйв это использовать BackgroundWorker и его событие RunWorkerCompleted
1
3 / 3 / 3
Регистрация: 26.02.2014
Сообщений: 49
14.06.2014, 15:59
Впервые задался вопросом сериализации!

Задача у меня такая пользователь создает по нажатию правой кнопкой мыши в этом месте pictureBox и так сколько угодно раз затем при нажатии правой кнопкой на нем он задает ему картинку. Хочу использовать показанный выше способ для сериализации всех данных о pictureBoxах что бы при последующей загрузке формы создать созданные пользователем контролы обратно. Как после такой сериализации это делать?
0
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.06.2014, 16:04
Цитата Сообщение от thisiswhite Посмотреть сообщение
Задача у меня такая пользователь создает по нажатию правой кнопкой мыши в этом месте pictureBox и так сколько угодно раз затем при нажатии правой кнопкой на нем он задает ему картинку. Хочу использовать показанный выше способ для сериализации всех данных о pictureBoxах что бы при последующей загрузке формы создать созданные пользователем контролы обратно. Как после такой сериализации это делать?
возможно достаточно сохранить только изображение?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
14.06.2014, 16:11
thisiswhite, только смени в методе сохранения на: FileMode.Create

Потому-что иногда могут быть косяки, если это не сделать
0
3 / 3 / 3
Регистрация: 26.02.2014
Сообщений: 49
14.06.2014, 16:13
А расположение и размеры подобранные пользователем?
Дело в том что количество box ов может меняться удаляться создоваться, а так же картинки иногда требуется менять.
И положение тоже придется менять пользователю иногда.

Как сохранить все эти изменения для поледующих запусков?

Добавлено через 1 минуту
Так же еще каждый Бох должен быть подписан но я думаю может самостоятельно контрол создать в котором будет и Лейбл и Пикчебокс чтоб проще хранить
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
14.06.2014, 16:16
thisiswhite, создай класс, хранящий описание этих картинок: позиция, путь к изображению. И при добавлении сохраняй в коллекцию эти данные, а потом при сохранении в файл передавай эту коллекцию для сериализации. При загрузке десериализуй этот список, а потом основываясь на данных в нём в цикле создавай эти pictureBoxы.
1
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.06.2014, 16:19
thisiswhite, тогда сохраняй PictureBox в List<PictureBox> , и эту коллекцию потом сериализуй.

Добавлено через 1 минуту
да если картинки нужно загружать из компьютера , то делай отдельный класс
1
3 / 3 / 3
Регистрация: 26.02.2014
Сообщений: 49
14.06.2014, 16:20
Воот так я и думал только я не пониамю как десереализовывать в принципе! Подскажите что б далеко не ходить?

Прям на вашем же примере пусть хоть теже параметры для загрузок процессов. Выведутся в соответствующие листбоксы к примеру. Спасибо заранее!
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
14.06.2014, 16:21
Лучший ответ Сообщение было отмечено Metall_Version как решение

Решение

Пример: Я пишу программу. При первом запуске появляется окно "введите логин и пароль". Вводим, ставим галочку, что "Запомнить". При следующем запуске мне нужно, чтобы программа могла автоматом получить сохранённые данные и если ставили ранее галочку то сразу авторизоваться и войти. Короче, как у того же скайпа поведение или любого адекватного мессенджера.

Вот классы, который я использую для хранения нужной инфы:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    [Serializable]
    public class AuthConfig
    {
        public AuthConfig()
            : this(null, false)
        {
        }
 
        public AuthConfig(AuthData data)
            : this(data, false)
        {
        }
 
        public AuthConfig(AuthData data, bool autoLogin)
        {
            Data = data;
            AutoLogin = autoLogin;
        }
 
        public AuthData Data { get; set; }
 
        public bool AutoLogin { get; set; }
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    [Serializable]
    public class AuthData
    {
        public AuthData()
            : this(string.Empty, string.Empty)
        {
        }
 
        public AuthData(string login, string password)
        {
            Login = login;
            Password = password;
 
        }
 
        public string Login { get; set; }
 
        public string Password { get; set; }
    }
Такие методы во вью модели окна авторизации:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
        #region Constructors
 
        public AuthorizationViewModel()
        {
            if (IsInDesignMode)
                return;
 
            AuthConfig authConfig = LoadAuthData();
            NeedSaveLoginAndPassword = true;
 
            if (authConfig != null)
            {
                if (authConfig.AutoLogin)
                {
                    OpenMainWindow(authConfig.Data);
                }
            }
            else
            {
                IsUIEnabled = true;
            }
        }
 
        #endregion
 
        #region Methods
 
        internal void OpenMainWindow(AuthData data)
        {
            var mainVm = new MainViewModel(this);
            if (mainVm.Authorize(data.Login, data.Password))
            {
                ResumeWorkRequested = true;
                WindowManager.Instance.CloseAuthorizationDialog();
                WindowManager.Instance.OpenMainWindow(mainVm);
            }
        }
 
        private void SignIn(PasswordBox exPasswordBox)
        {
            if (!string.IsNullOrEmpty(exPasswordBox.Password))
            {
                var data = new AuthData(Login, exPasswordBox.Password);
                var authConfig = new AuthConfig(data, true);
                if (NeedSaveLoginAndPassword)
                {
                    SaveEncrypted(authConfig);
                }
                OpenMainWindow(data);
            }
            else
            {
                MessageBox.Show("Введите пароль");
            }
        }
 
        public void SaveEncrypted(AuthConfig config)
        {
            AuthData encryptedData = AuthSecurity.Encrypt(config.Data.Login, config.Data.Password);
            config.Data = encryptedData;
            DataSerializer<AuthConfig>.SaveObjectToXml(config, Global.Files.AuthDataFile);
        }
 
        public AuthConfig LoadDecrypted()
        {
            AuthConfig config = null;
            try
            {
                config = DataSerializer<AuthConfig>.LoadObjectFromXml(Global.Files.AuthDataFile);
                config.Data = AuthSecurity.Decrypt(config.Data);
            }
            catch (Exception)
            {
                Process.Start(Global.Folders.MainData);
                Debug.Fail("Не удалось загрузить файл");
            }
            return config;
        }
 
        private AuthConfig LoadAuthData()
        {
            AuthConfig authConfig = null;
 
            Global.Folders.CheckFolders();
            if (File.Exists(Global.Files.AuthDataFile))
            {
                try
                {
                    authConfig = LoadDecrypted();
                    Login = authConfig.Data.Login;
                    Password = authConfig.Data.Password;
                }
                catch (Exception)
                {
                    Process.Start(Global.Folders.MainData);
                    Process.Start(Global.Files.AuthDataFile);
                }
            }
 
            return authConfig;
        }
1
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.06.2014, 16:22
thisiswhite, http://msdn.microsoft.com/ru-r... .110).aspx
там пример есть
1
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
14.06.2014, 16:29
Обновил код. Вот видно как в конструкторе происходит вызов десериализации

Добавлено через 2 минуты
Цитата Сообщение от thisiswhite Посмотреть сообщение
Воот так я и думал только я не пониамю как десереализовывать в принципе! Подскажите что б далеко не ходить?
Так у меня же в примере всё показано как. В том, что старое моё сообщение. Только там не забудь в методах сохранения сменить FileMode на Create
1
3 / 3 / 3
Регистрация: 26.02.2014
Сообщений: 49
14.06.2014, 17:36
Вечерком приду попробую своять из этого, отпишусь потом=)
0
3 / 3 / 3
Регистрация: 26.02.2014
Сообщений: 49
16.06.2014, 04:49
Разобрался=)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.06.2014, 04:49
Помогаю со студенческими работами здесь

Keybd_event в других приложениях
По bluetooth с телефона посылаю сообщение на сервер. В зависимости от того, какое пришло сообщение, нажимается та или иная клавиша...

Создание класса содержащего методы для использования в других классах
ПОМОГИТЕ решить проблему: Нужно сделать класс в котором надо собрать часто используемые методы, для работы с базой данных, чтобы потом...

Сигналы/слоты Qt в dll библиотеке для использования в других языках
Есть программа, написанная на Qt, и есть dll библиотека, также написанная на Qt. Они работают в разных потоках и &quot;общаются&quot; между...

Сборка не работает на других машинах (Dll для использования в MSOffice)
Добрый день! Сделал Dll для использования в MSOffice, собрал: на той машине, где собирал - работает. Но стоит перенести на другую -...

Написать dll для дальнейшего использования в программах на других языках
как правильно написать dll чтоб ей можно было пользоваться программам на других языках, например, на delphi


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru