Как сохранить данные с WinForm?

Вопрос может быть и глупый но все же. К примеру имеется форма на которой расположены textbox1, textbox2 и так далее. Уточню что textbox не обязательное имя для контрола, может быть txbUserName и так далее. Дак вот как сохранить введенные данные? А потом прочитать из файла?
  • Вопрос задан
  • 4129 просмотров
Решения вопроса 2
DarkRaven
@DarkRaven
разработка программного обеспечения
Вообще, я бы сделал бы модель данных, привязал бы ее к контролам через DataBindings и сохранял/загружал бы уже именно ее.

Пример с формой входа (на форме два текстовых поля, txtUserName и txtPassword, и две кнопки, buttonSave и buttonLoad):
Форма
public partial class Form1 : Form
{
    private readonly LoginViewModel viewModel;

    public Form1()
    {
        InitializeComponent();

        viewModel = new LoginViewModel();

        txtUserName.DataBindings.Add(new Binding("Text", viewModel, "UserName", false, DataSourceUpdateMode.OnPropertyChanged));
        txtPassword.DataBindings.Add(new Binding("Text", viewModel, "Password", false, DataSourceUpdateMode.OnPropertyChanged));

    }

    private void buttonSave_Click(object sender, EventArgs e)
    {
        var file = GetFilePath();

        using (var buffer = File.OpenWrite(file))
        {
            var formatter = new BinaryFormatter();

            formatter.Serialize(buffer, viewModel);
        }
    }

    private void buttonLoad_Click(object sender, EventArgs e)
    {
        var model = LoadContent() as LoginViewModel;

        if (model != null)
        {
            viewModel.Password = model.Password;
            viewModel.UserName = model.UserName;
        }
    }

    private static object LoadContent()
    {
        var file = GetFilePath();

        if (!File.Exists(file))
            return null;

        using (var buffer = File.OpenRead(file))
        {
            var formatter = new BinaryFormatter();

            try
            {
                return formatter.Deserialize(buffer);
            }
            catch
            {
                //TODO Add error handling
                return null;
            }
        }
    }

    private static string GetFilePath()
    {
        var directory = Path.GetDirectoryName(typeof(Form1).Assembly.Location);
        return Path.Combine(directory, "store.txt");
    }
}


Модель:
[Serializable]
public class LoginViewModel : INotifyPropertyChanged
{
    private string _userName;
    private string _password;

    public string UserName
    {
        get { return _userName; }
        set
        {
            _userName = value;
            NotifyPropertyChanged(nameof(UserName));
        }
    }

    public string Password
    {
        get { return _password; }
        set
        {
            _password = value;
            NotifyPropertyChanged(nameof(Password));
        }
    }

    private void NotifyPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;
}


Как такого прямого процесса сериализации и десереализации формы нет, т.к. там очень много вещей в бэкграунде (свойства, события и т.п.), которые мешают этому процессу.

Один из вариантов обхода, это именно DataBindings, как я показал на примере.
Ответ написан
Комментировать
@sedoi_starik Автор вопроса
С этим все понятно.
Грубо говоря запись осуществляется так:
sw.WriteLine(txbUserName.Text); //сохранение имени пользователя из textbox
sw.WriteLine(txbUserPassword.Text);//сохранение пароля пользователя из textbox
С двумя контролами это нормально. Но когда их штук 20 на форме. Да еще и разные. Все тоже в ручную? Нет такого WinForm->File->WinForm?

Нашел по этому поводу типа статьи.
www.cyberforum.ru/windows-forms/thread1558189.html
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
arxont
@arxont
C# программист
Как вариант можете сохранять в XML. Вот пример кода, который пробегается по всем TextBox`ам и сохраняет их в
файл
const string filename = "file.xml";
private void Form1_Load(object sender, EventArgs e)
{
    if (!File.Exists(filename)) return;

    var doc = XDocument.Load(filename);

    foreach (Control control in this.Controls)
    {
        if (control is TextBox)
        {
            var element = doc.Root.Elements().FirstOrDefault(x => x.Name == control.Name);
            control.Text = (element != null) ? element.Value : "";
        }
    }
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    var element = new XElement("Settings");

    foreach (Control control in this.Controls)
    {
        if (control is TextBox)
        {
            element.Add(new XElement(control.Name, control.Text));
        }
    }

    XDocument doc = new XDocument(element);
    doc.Save(filename);
}
Ответ написан
@d-stream
Готовые решения - не подаю, но...
Правильный путь - вязать к полям формы поля объекта, читать-сохранять - объект. Точнее научить объект сохраняться при необходимости и загружаться например при создании.

Извращенный - крутиться циклом по всем элементам формы и читать-писать пары имя-значение, потом иметь море секса при изменении/переименовании элементов -)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы