Как сохранять windows form
Это действительно расстраивает меня. Я новичок в C Sharp, поэтому ища некоторую помощь. My Save/Save As полностью фубар.
Как сохранить изменения в существующий файл без появления диалогового окна сохранения? Если я нажму "Сохранить" , откроется диалоговое окно, в котором я сохраню его, а затем сделаю некоторые изменения и снова нажмите "Сохранить" , он выталкивает диалоговое окно, а не просто сохраняет файл с уже указанным именем.
Как показать имя файла, а не полный путь в диалоговом окне сохранения? Он отображается как имя файла: C:\Users\имя_пользователя\desktop\save\filename.xml
Это в MainForm.cs.
Это в EditForm.cs
Спасибо, что помогли мне так быстро! В настоящее время My Save работает, как ожидалось, однако в нем появилась странная проблема с Save As (код выше).
Если я открою файл (test.xml), который я сохранил, затем нажмите "Сохранить как" (name it test2.xml), он сохранит новый файл. НО, когда я снова открываю этот test.xml и вношу изменения, и нажмите "Сохранить" , он сохранит эти изменения в test2.xml. Очень странно. любые идеи?
спросил(а) 2011-07-08T01:04:00+04:00 10 лет, 4 месяца назадГде в коде установлено значение FileName? Из образца, который вы опубликовали, я не вижу, чтобы его устанавливали в любом месте, но, возможно, это где-то еще. Это может работать:
ответил(а) 2011-07-08T01:49:00+04:00 10 лет, 4 месяца назад1) Save dialog box просто вернет путь к файлу, который пользователь хочет сохранить. Используя этот путь, вы можете выполнить свою функцию сохранения. Если вы хотите сохранить текущий документ, просто пропустите диалоговое окно и выполните функцию сохранения с кешированной версией выбранного пути.
Например, в вашей форме есть переменная:
Когда пользователь сначала открывает диалоговое окно "Сохранить", заполните эту переменную с помощью пути, который выбрал пользователь.
В следующий раз, когда пользователь сохранит (вместо save as ), выполните проверку:
SaveFileDialogКомпонент позволяет пользователям просматривать файловую систему и выбирать файлы для сохранения. Диалоговое окно возвращает путь и имя файла, который пользователь выбрал в диалоговом окне. Тем не менее для фактического сохранения файла на диск необходимо написать специальный код.
Сохранение файла с помощью компонента SaveFileDialog
Выведите на экран диалоговое окно Сохранить файл и вызовите метод для сохранения файла, выбранного пользователем.
SaveFileDialog OpenFile Чтобы сохранить файл, используйте метод компонента. Этот метод предоставляет объект, который Stream можно записать в.
В приведенном ниже примере DialogResult свойство используется для получения имени файла, а OpenFile метод — для сохранения файла. OpenFileМетод предоставляет поток для записи файла.
В приведенном ниже примере имеется Button элемент управления с назначенным ему изображением. При нажатии кнопки создается SaveFileDialog экземпляр компонента с фильтром, который разрешает файлы типа .jpg, JPEG и .bmp. При выборе файла такого типа в диалоговом окне "Сохранить файл" изображение кнопки сохраняется.
Чтобы получить или задать FileName свойство, сборке требуется уровень привилегий, предоставляемый System.Security.Permissions.FileIOPermission классом. Если процесс выполняется в контексте с частичным доверием, он может сгенерировать исключение из-за недостатка привилегий. Дополнительные сведения см. в разделе Code Access Security Basics.
В примере предполагается, что в форме есть Button элемент управления, Image свойство которого установлено в файл типа .jpg, jpeg или .bmp.
FileDialog FilterIndex Свойство класса (из-за наследования является частью SaveFileDialog класса) использует индекс, отсчитываемый от единицы. Это важно при написании кода для сохранения данных в определенном формате (например, в формате обычного текста или двоичном формате). Это свойство представлено в следующем примере.
Дополнительные сведения о записи файловых потоков см. в статьях BeginWrite и Write .
Некоторые элементы управления, такие как RichTextBox элемент управления, имеют возможность сохранять файлы.
RichTextBoxэлемент управления Windows Forms может записывать отображаемые сведения в одном из следующих форматов:
с обычным текстом;
Обычный текст в Юникоде
Формат Rich-Text (RTF)
RTF с пробелами вместо объектов OLE
Обычный текст с текстовым представлением объектов OLE
Чтобы сохранить файл, вызовите SaveFile метод. Можно также использовать метод SaveFile для сохранения данных в поток. Дополнительные сведения см. в разделе SaveFile(Stream, RichTextBoxStreamType).
Сохранение содержимого элемента управления в файле
Определите путь к файлу, который необходимо сохранить.
Для этого в реальном приложении обычно используется SaveFileDialog компонент. Общие сведения см. в разделе Общие сведения о компоненте SaveFileDialog.
Вызовите SaveFile метод RichTextBox элемента управления, указав файл для сохранения и, при необходимости, тип файла. При вызове метода с именем файла в качестве единственного аргумента файл будет сохранен как RTF. Чтобы указать другой тип файла, вызовите метод со значением перечисления RichTextBoxStreamType в качестве второго аргумента.
В приведенном ниже примере путь, заданный для расположения RTF-файла, является папкой " Мои документы ". это расположение используется, поскольку можно предположить, что большинство компьютеров, работающих под управлением операционной системы Windows, будут содержать эту папку. Выбор этого расположения также позволяет пользователям с минимальными уровнями доступа к системе безопасно запускать приложение. В приведенном ниже примере предполагается, что форма с RichTextBox уже добавленным элементом управления.
В этом примере создается файл (если файл отсутствует). Если приложению требуется создать файл, этому приложению требуется доступ для создания папки. Для задания разрешений используются списки управления доступом. Если файл уже существует, приложению требуется только доступ на запись, чем меньше привилегия. Там, где это возможно, более безопасно создавать файл во время развертывания и предоставлять доступ только для чтения к одному файлу, а не к папке. По тем же соображениям рекомендуется записывать данные в пользовательские папки, а не в коревую папку или папку Program Files.
Теперь я хочу сохранить значение пути в файл для дальнейшего использования. Это будет одна из многих настроек, сохраненных в этом файле. Этот файл будет находиться прямо в папке приложения.
Насколько я понимаю, доступны три варианта:
- Файл ConfigurationSettings (appname.exe.config)
- Реестр
- Пользовательский файл XML
Означает ли это, что я должен использовать собственный XML-файл для сохранения настроек конфигурации?
Я видел и другие дискуссии на эту тему, но мне это все еще непонятно.
Этот метод применим как для консоли, так и для Windows Forms и других типов проектов.
Обратите внимание, что вам нужно установить объем свойство ваших настроек. Если вы выберете Область применения, затем Настройки.По умолчанию. будет только для чтения.
Если вы планируете сохранить файл в том же каталоге, что и ваш исполняемый файл, вот хорошее решение, использующее формат JSON:
Реестр запрещен. Вы не уверены, имеет ли пользователь, использующий ваше приложение, достаточные права для записи в реестр.
Вы можете использовать app.config файл для сохранения настроек уровня приложения (которые одинаковы для каждого пользователя, использующего ваше приложение).
Я бы сохранил пользовательские настройки в XML-файле, который будет сохранен в изолированном хранилище или в каталоге SpecialFolder.ApplicationData.
В ApplicationSettings класс не поддерживает сохранение настроек в app.config файл. Это очень задумано; приложения, которые запускаются с должным образом защищенной учетной записью (например, Vista UAC), не имеют доступа на запись в папку установки программы.
- Не могли бы вы расширить свое последнее предложение? Попросите повышения прав, чтобы написать app.config или написать отдельное приложение, которое проходило бы через домашние программы всех пользователей, искало user.config и редактировало их?
- 2 Для отдельной программы требуется манифест для запроса повышения. Погуглите asinvoker requireadministrator, чтобы найти правильный синтаксис. Редактировать user.config нецелесообразно и не нужно.
Аргумент registry / configurationSettings / XML все еще кажется очень активным. Я использовал их все по мере развития технологии, но мой фаворит основан на системе Threed в сочетании с изолированным хранилищем.
Следующий пример позволяет сохранять объекты с именем properties в файл в изолированном хранилище. Такие как:
Свойства можно восстановить с помощью:
Это просто образец, не предлагающий лучших практик.
- 1 Или еще лучше; использовать DataContractJsonSerializer
Я хотел поделиться библиотекой, которую я создал для этого. Это крошечная библиотека, но большое улучшение (IMHO) по сравнению с файлами .settings.
Библиотека называется Jot (GitHub). Вот старая статья в The Code Project, которую я написал об этом.
Вот как вы могли бы использовать его для отслеживания размера и местоположения окна:
Преимущество по сравнению с файлами .settings: В нем значительно меньше кода, и он намного менее подвержен ошибкам, поскольку вам нужно только упомянуть каждое свойство. один раз.
В файлах настроек вам необходимо указать каждое свойство 5 раз: один раз, когда вы явно создаете свойство, и еще четыре раза в коде, который копирует значения туда и обратно.
Хранение, сериализация и т. Д. Полностью настраиваются. Когда целевые объекты создаются контейнером IoC, вы можете [подключить его] [], чтобы он автоматически применял отслеживание ко всем объектам, которые он разрешает, так что все, что вам нужно сделать, чтобы сделать свойство постоянным, - это установить [Trackable] атрибут на нем.
Он легко настраивается, и вы можете настроить: - когда данные сохраняются и применяются глобально или для каждого отслеживаемого объекта - как они сериализуются - где они хранятся (например, файл, база данных, онлайн, изолированное хранилище, реестр) - правила, которые могут отменять применение / сохраняющиеся данные для свойства
Поверьте, библиотека на высшем уровне!
Простой способ - использовать объект данных конфигурации, сохранить его как XML-файл с именем приложения в локальной папке и при запуске прочитать его обратно.
Вот пример для хранения положения и размера формы.
Объект данных конфигурации строго типизирован и прост в использовании:
Класс менеджера для сохранения и загрузки:
Теперь вы можете создать экземпляр и использовать в своей форме события загрузки и закрытия:
И созданный XML-файл также доступен для чтения:
Мне не нравится предлагаемое решение использования web.config или же app.config . Попробуйте прочитать свой собственный XML. Посмотри на Файлы настроек XML Больше никаких web.config.
Другие варианты, вместо использования настраиваемого файла XML, мы можем использовать более удобный для пользователя формат файла: файл JSON или YAML.
Вы можете хранить свой файл настроек в нескольких специальных папках (для всех пользователей и для каждого пользователя), как указано здесь Environment.SpecialFolder Enumeration и в нескольких файлах (по умолчанию только для чтения, для каждой роли, для каждого пользователя и т. Д.)
Если вы решите использовать несколько настроек, вы можете объединить эти настройки: например, объединение настроек по умолчанию + BasicUser + AdminUser. Вы можете использовать свои собственные правила: последнее имеет приоритет над значением и т. Д.
Например, если такой файл конфигурации
Мы можем получить такие значения
- 2 Неправда .. см. Ответ aku выше. это возможно с помощью настроек и ApplicationSettingsBase
Иногда вам нужно избавиться от этих настроек, хранящихся в традиционном файле web.config или app.config. Вам нужен более точный контроль над развертыванием записей настроек и разделенным дизайном данных. Или требуется включить добавление новых записей во время выполнения.
Могу представить два хороших варианта:
- Строго типизированная версия и
- Объектно-ориентированная версия.
Преимущество строго типизированной версии - строго типизированные имена и значения настроек. Нет риска смешивания имен или типов данных. Недостатком является то, что нужно закодировать больше настроек, их нельзя добавить во время выполнения.
Преимущество объектно-ориентированной версии состоит в том, что новые настройки могут быть добавлены во время выполнения. Но у вас нет строго типизированных имен и значений. Будьте осторожны со строковыми идентификаторами. При получении значения необходимо знать тип данных, сохраненный ранее.
Вы можете найти код обеих полнофункциональных реализаций ЗДЕСЬ.
Да, можно сэкономить конфигурация - но это в значительной степени зависит от того, как вы решите это сделать. Позвольте мне описать технические различия, чтобы вы могли понять, какие у вас есть варианты:
Во-первых, вам нужно различить, хотите ли вы использовать настройки приложения или же AppSettings в вашем *.exe.config (он же App.config в Visual Studio) файл - есть принципиальные отличия, здесь описано.
Оба предоставляют разные способы сохранения изменений:
-
В AppSettings позволяют читать и писать прямо в файл конфигурации (через config.Save(ConfigurationSaveMode.Modified); , где config определяется как config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); ).
Заметка: Как уже упоминалось в вопросе, есть 3-й вариант: Если вы рассматриваете файл конфигурации как XML-документ, вы можете загружать, изменять и сохранять его, используя System.Xml.Linq.XDocument класс. Нет необходимости использовать собственный XML-файл, вы можете прочитать существующий файл конфигурации; для запросов к элементам вы даже можете использовать запросы Linq. Я привел пример Вот, ознакомьтесь с функцией GetApplicationSetting там в ответ.
Если вам требуется шифрование для защиты ваших ценностей, проверять, выписываться это ответ.
Расставим третью группу элементов. Добавим поле расширенной работы с текстом и организуем небольшой текстовый редактор с сохранением и открытием файлов, а также добавим контекстное меню по щелчку правой кнопки мыши на любой пустой позиции формы.
Расставим третью группу следующим образом:
Рис. 5. 1. Расстановка элементов третьей группы (Открытие файла, сохранение файла и работа с текстом)
Перетащим с панели элементов новый элемент ContextMenuStrip. Установим для него свойство ( Name ): MenuRight. Заполним его элементами также как и главное меню Файл:
Если редактирование прямо на форме не слишком наглядно, можно также воспользоваться расширенным редактором коллекции элементов для меню. Он также подходит для обычного меню MenuStrip, элемента ToolStrip и строки состояния StatusStrip.
Рис. 6. 1. Редактор коллекции элементов (для MouseRight)
С панели инструментов добавим также элементы диалоговых окон сохранения и загрузки: OpenFileDialog и FileSaveDialog. Установим им имена ( Name ) соответственно: FileOpen и FileSave:
Свойства элемента FileSave:
(Name): | FileSave |
FileName: | Документ |
^ Здесь указываем название файл без разширения по умолчанию.
InitialDirectory: | <ваш путь> |
Если нужно указать стартовую директорию для сохранения. Путь может выглядеть так: D :\ Folder 1\ Folder 2
DefaultExt: | Файлы RTF|*.rtf |
^ Здесь указывается суффикс файла сохранения и название этого суффикса.
Filter: | Файлы RTF|*.rtf|Текстовый документ|*.txt|Текст OpenDocument|*.odt|Все файлы|*.* |
ПРИМЕЧЕНИЕ № 4: Свойства DefaultExt и Filter записываются через разделители «|». Напомним, что в лабораторных работах данного практикума запись значений для полей свойств элементов управления иногда такова: «Имя свойства: <Значение>.» — точка после закрывающей кавычки не относится к значению, поэтому не стоит заносить скажем в поле принимающее только целое числовое значение ещё и точку. Среда выдаст ошибку либо уберёт точку.
Пример (задание точки в имени элемента):
Рис. 6. 2. Ошибочное задание поля ( Name )
Свойства элемента FileOpen:
(Name): | FileOpen |
FileName: | Документ |
^ Здесь указываем название файл без расширения по умолчанию.
Имена остальных элементов оставляем как есть:
( Name ): | button10 |
Text: | Цвет |
ToolTip на Hint: | Цвет выделенного текста |
(Name): | button11 |
Text: | Шрифт |
ToolTip на Hint: | Шрифт выделенного текста |
(Name): | button14 |
Text: | Фон |
ToolTip на Hint: | Фон выделенного текста |
( Name ): | button15 |
Text: | Копировать |
ToolTip на Hint: | Копировать выделенный текст в буфер обмена |
(Name): | button13 |
Text: | Выделить всё |
(Name): | button12 |
Text: | Очистить |
Событие Click кнопки Цвет:
private void button10_Click(object sender, EventArgs e)
richTextBox1.SelectionColor = ColorSelect.Color; // Меняем цвет выделенного текста richTextBox1
Событие Click кнопки Шрифт:
private void button11_Click(object sender, EventArgs e)
richTextBox1.SelectionFont = FontSelect.Font; // Меняем шрифт выделенного текста richTextBox1
// Ловим ошибку: шрифт не TrueType
Событие Click кнопки Фон:
private void button14_Click(object sender, EventArgs e)
richTextBox1.SelectionBackColor = ColorSelect.Color; // Меняем фон выделенного текста richTextBox1
Событие Click кнопки Копировать:
private void button15_Click(object sender, EventArgs e)
richTextBox1.Copy(); // Копируем выделенный фрагмент текста в элементе
Событие Click кнопки Очистить:
private void button12_Click(object sender, EventArgs e)
richTextBox1.Clear(); // Очистка richTextBox1
Событие Click кнопки Выделить всё:
private void button13_Click(object sender, EventArgs e)
richTextBox1.Focus(); // Фокус на элемент
richTextBox1.SelectAll(); // Выделяем весь текст
Событие Click кнопки главного меню Открыть:
private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
// Открываем диалог открытия файла
// Создаём поток для содержимого файла
Stream FStream = FileOpen.OpenFile();
// Загружаем файл (открываем форматированный текст)
// Закрываем поток и высвобождаем память
this.Text = Title + " :: " + FileOpen.FileName;
// Ловим ошибку: файл не найден
Событие Click кнопки главного меню Сохранить как…:
private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
// Создаём строковую переменную для хранения имени сохранённого файла
// Создаём поток в памяти
MemoryStream MStream = new MemoryStream();
// Cоздаём поток для файл
if (FileSave.ShowDialog() == DialogResult.OK) // По завершении диалога и нажатии кнопки ОК.
// Связываем поток с именем существующего файла, если файла нет, то создаём новый файл
// Меняем положение в потоке
// Сохраняем в поток содержимое richTextBox1 (сохраняем форматированный текст)
// Записываем информацию в файл
// Закрываем поток и высвобождаем память
this.Text = Title + " :: " + FileSavedAs; // После сохранения укажем сохранённый файл в заголовке
Модифицируем событие Click кнопки :
private void button4_Click(object sender, EventArgs e)
SaveQuestion(); // Вызов метода обработки "правильного" закрытия предложения с выводом диалога сохранения данных
Сам метод SaveQuestion (), добавим в этом же файле LWP 05 Main . cs:
DialogResult Result = MessageBox.Show("Сохранить изменения в документе?", Title + " :: Сохранение изменений", MessageBoxButtons.YesNo);
switch (Result) // Оператор переключения switch, получает значения Result результата выполнения диалога
сохранитьToolStripMenuItem_Click(null, null); // Генерируем событие нажатия кнопки Сохранить как.
В начале файла добавим строковую переменную:
public partial class LWP05Main : Form
String Title; // Строковая переменная для хранения заголовка приложения
Модифицируем метод LWP 05 Main () следующим образом:
/* Инициализируем массив элементов для checkedListBox1 */
/* Устанавливаем режим выбора 'ktvtynf с двойного нажатия на одинарный */
NumericAplha.Value = 100; // Начальное значение
progressBar1.Maximum = 60; // Граница индикаторы выполнения
Title = this.Text; // Сохраняем первоначальный заголовок
Теперь обработаем контекстное меню. События Click кнопок контекстного меню Открыть, Сохранить как … и Выход:
private void открытьToolStripMenuItem1_Click(object sender, EventArgs e)
открытьToolStripMenuItem_Click(null, null); // Вызываем метод события Click главного меню для пункта Открыть
private void сохранитьКакToolStripMenuItem_Click(object sender, EventArgs e)
сохранитьToolStripMenuItem_Click(null, null); // Вызываем метод события Click главного меню для пункта Сохранить как.
private void выйтиToolStripMenuItem_Click(object sender, EventArgs e)
События MouseEnter оставшихся кнопок главного меню:
private void открытьToolStripMenuItem_MouseEnter(object sender, EventArgs e)
StatusLabel.Text = открытьToolStripMenuItem1.Text + " (" + открытьToolStripMenuItem1.ShortcutKeyDisplayString + ")";
private void сохранитьToolStripMenuItem_MouseEnter(object sender, EventArgs e)
StatusLabel.Text = сохранитьКакToolStripMenuItem.Text + " (" + сохранитьКакToolStripMenuItem.ShortcutKeyDisplayString + ")";
Компилируем, проверяем работоспособность:
Рис. 6. 3. Окончательная работа третьего блока (Открытие файла, сохранение файла и работа с текстом)
Читайте также: