Подскажите пожалуйста как записать данные в объект класса в формы DataGridView. Мне нужно считать все строки с формы для дальнейшей сериализации. Для этого, я так понимаю, надо создать массив объектов класса и через цикл записывать туда данные с формы... Но как?) Класс:
[Serializable]
public class Person
{
public string name { get; set; }
public string surename { get; set; }
public string birthday { get; set; }
public string sex { get; set; }
public string country { get; set; }
public string city { get; set; }
public int growth { get; set; }
public int weight { get; set; }
public string hair_color { get; set; }
public string eye_color { get; set; }
public string zodiac_sign { get; set; }
public Person()
{
name = null;
surename = null;
birthday = null;
sex = null;
country = null;
city = null;
growth = 0;
weight = 0;
hair_color = null;
eye_color = null;
zodiac_sign = null;
}
}
и вот часть кода, где должно быть по нажатию на кнопку считывание данных с формы
private void btSave_Click(object sender, EventArgs e)
{
Person[] persons = new Person[dataGridView1.RowCount];
for(int i = 0; i < dataGridView1.RowCount; i++)
{
persons[i] = new Person();
//Дальше загвоздка...
}
}
Заметил еще с вашего прошлого вопроса, что пока вам никто не помог. Приведу пример по следам вашего кода из прошлого вопроса.
Создаем такую модель, с поддержкой проверки значений свойств.
[Serializable]
public class Person : IDataErrorInfo
{
public int Id { get; set; }
public string Name { get; set; }
public string Surename { get; set; }
public DateTime Birthday { get; set; }
public string Sex { get; set; }
public int Weight { get; set; }
//эти свойства я убрал, чтоб слегка облегчить пример
//public string Country { get; set; }
//public string City { get; set; }
//public int Height { get; set; }
//public string HairColor { get; set; }
//public string EyeColor { get; set; }
//public string ZodiacSign { get; set; }
#region Реализация IDataErrorInfo
public string Error => String.Empty;
public string this[string columnName]
{
get
{
if (columnName.Equals(nameof(Name)) && String.IsNullOrEmpty(Name))
{
return "Введите имя";
}
if (columnName.Equals(nameof(Name)) && Name.Any(c => Char.IsDigit(c)))
{
return "Имя не должно содержать цифры";
}
if (columnName.Equals(nameof(Surename)) && String.IsNullOrEmpty(Surename))
{
return "Введите фамилию";
}
if (columnName.Equals(nameof(Surename)) && Surename.Any(c => Char.IsDigit(c)))
{
return "Фамилия не должна содержать цифры";
}
if (columnName.Equals(nameof(Sex)) && String.IsNullOrEmpty(Sex))
{
return "Выберите пол";
}
if (columnName.Equals(nameof(Weight)) && Weight <= 5)
{
return "Введите вес в килограммах";
}
if (columnName.Equals(nameof(Birthday)) &&
(Birthday <= DateTime.Now.AddYears(-100) || Birthday > DateTime.Now.AddYears(-1)))
{
return "Введите дату рождения правильно";
}
return String.Empty;
}
}
#endregion
}
Теперь надо задуматься о так называемом слое хранения данных (файл XML или работа с БД). Для этого создадим абстракцию Хранилища (Repository) в виде интерфейса
public interface IPersonRepository
{
Task<List<Person>> GetPeople();
Task<bool> AddPerson(Person person);
}
здесь пока объявлены 2 метода, потом вы можете добавить еще какие понадобятся вам по ходу разработки программы. Теперь тестовый класс хранилища, который будет работать с данными в опер.памяти. Такой репозиторий полезен, когда вы разрабатываете прототип программы и отвлечение на работу с конкретной базой данных или записью в файлы, только отвлекает от сути и влечет за собой возможность возникновения доп. ошибок. Вот такой простой тестовый репозиторий
public class PersonTestRepository : IPersonRepository
{
private readonly List<Person> _people;
//ctor
public PersonTestRepository()
{
_people = new List<Person>
{
new Person { Id = 1, Name = "Андрей", Surename = "Миронов", Sex = "мужской", Birthday = DateTime.Parse("23.05.1989"), Weight = 86 },
new Person { Id = 2, Name = "Владислав", Surename = "Смирнов", Sex = "мужской", Birthday = DateTime.Parse("03.12.1983"), Weight = 75 },
new Person { Id = 3, Name = "Вера", Surename = "Брежнева", Sex = "женский", Birthday = DateTime.Parse("29.08.1998"), Weight = 55 },
};
}
public Task<bool> AddPerson(Person person)
{
if (person == null)
throw new ArgumentNullException(nameof(person));
if (person.Id != 0)
throw new ArgumentException(nameof(person));
if (_people.Count == 0)
{
person.Id = 1;
}
else
{
person.Id = _people.Max(p => p.Id) + 1;
}
_people.Add(person);
return Task.FromResult(true);
}
public Task<List<Person>> GetPeople()
{
return Task.FromResult(_people);
}
}
Теперь реализация форм, вот главная
public partial class MainView : Form
{
//источник данных для DGV
private BindingSource _bsPeople = new BindingSource();
public MainView()
{
InitializeComponent();
//привязки
SetBindings();
this.StartPosition = FormStartPosition.CenterScreen;
this.Text = "Пример";
this.Load += MainView_Load;
_buttonAddPerson.Click += ButtonAddPerson_Click;
}
/// <summary>
/// Установка привязок
/// </summary>
private void SetBindings()
{
_dataGridViewPeople.AutoGenerateColumns = false;
_dataGridViewPeople.DataSource = _bsPeople;
_columnPersonName.DataPropertyName = nameof(Person.Name);
_columnPersonSurename.DataPropertyName = nameof(Person.Surename);
_columnPersonSex.DataPropertyName = nameof(Person.Sex);
_columnPersonBirthday.DataPropertyName = nameof(Person.Birthday);
_columnPersonWeight.DataPropertyName = nameof(Person.Weight);
}
/// <summary>
/// Загружаем данные для DGV
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void MainView_Load(object sender, EventArgs e)
{
//получем коллекцию людей
List<Person> people = await Program.PersonRepository.GetPeople();
//заполняем источник данных
people.ForEach(p => _bsPeople.Add(p));
}
/// <summary>
/// Добавление новой записи о человеке
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void ButtonAddPerson_Click(object sender, EventArgs e)
{
using (var editView = new EditView())
{
//готовим форму
editView.Owner = this;
editView.StartPosition = FormStartPosition.CenterParent;
editView.Text = "Создание новой записи";
//назначаем экземпляр нового чела
editView.CurrentPerson = new Person() { Birthday = DateTime.Now };
//отображаем форму, ждем ответа
if (editView.ShowDialog() == DialogResult.OK)
{
//запоминаем
await Program.PersonRepository.AddPerson(editView.CurrentPerson);
//перезагружаем коллекцию людей
_bsPeople.Clear();
var people = await Program.PersonRepository.GetPeople();
people.ForEach(p => _bsPeople.Add(p));
}
}
}
}
обратите внимание, что я работаю через привязки. И в качестве источника данных для DGV у меня служит экземпляр BindingSource
(это к слову ответ на ваш вопрос).
Теперь форма редактирования человека
public partial class EditView : Form
{
private BindingSource _bsPerson = new BindingSource();
public EditView()
{
InitializeComponent();
//привязки
SetBindings();
//роли кнопок
this.AcceptButton = _buttonOK;
this.CancelButton = _buttonCancel;
//кнопка ОК отдает результат
_buttonOK.Click += (s, e) => this.DialogResult = DialogResult.OK;
//радиокнопки
_radioButtonMale.CheckedChanged += RadioButton_CheckedChanged;
_radioButtonFemale.CheckedChanged += RadioButton_CheckedChanged;
}
/// <summary>
/// Текущий редактируемый чел
/// </summary>
public Person CurrentPerson
{
get => _bsPerson.Current as Person;
set => _bsPerson.Add(value);
}
/// <summary>
/// Установка привязок
/// </summary>
private void SetBindings()
{
_textBoxName.DataBindings.Add("Text", _bsPerson, nameof(Person.Name),
true, DataSourceUpdateMode.OnPropertyChanged);
_textBoxSurename.DataBindings.Add("Text", _bsPerson, nameof(Person.Surename),
true, DataSourceUpdateMode.OnPropertyChanged);
_textBoxWeight.DataBindings.Add("Text", _bsPerson, nameof(Person.Weight),
true, DataSourceUpdateMode.OnPropertyChanged);
_textBoxSex.DataBindings.Add("Text", _bsPerson, nameof(Person.Sex),
true, DataSourceUpdateMode.OnPropertyChanged);
_dateTimePickerBirthday.DataBindings.Add("Text", _bsPerson, nameof(Person.Birthday),
true, DataSourceUpdateMode.OnPropertyChanged);
//отображение ошибок
_errorProvider.DataSource = _bsPerson;
//доступность кнопки OK через событие изменения свойств чела
_bsPerson.CurrentItemChanged += _bsPerson_CurrentItemChanged;
}
/// <summary>
/// Проверка значения свойств чела и вкл./выкл. кнопки ОК
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _bsPerson_CurrentItemChanged(object sender, EventArgs e)
{
string error = String.Empty;
//пробегаем по всем свойствам чела и собираем значения ошибок
foreach (var prop in CurrentPerson.GetType().GetProperties())
{
error += CurrentPerson[prop.Name];
}
//вкл./выкл. кнопки ОК
_buttonOK.Enabled = String.IsNullOrEmpty(error);
//Debug.WriteLine($"error: {error}");
}
/// <summary>
/// Радиокнопки, присвоение пола челу
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
var rb = sender as RadioButton;
if (rb.Checked)
{
if (rb.Text.Equals("М"))
{
_textBoxSex.Text = "мужской";
}
else
{
_textBoxSex.Text = "женский";
}
}
}
}
Что бы это как то запустить изменим Program.cs
static class Program
{
public static IPersonRepository PersonRepository { get; private set; }
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
PersonRepository = new PersonTestRepository(); //данные в памяти программы
//репозиторий реальный пишем/читаем XML файл
//var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "people.xml");
//PersonRepository = new PersonXmlRepository(path);
Application.Run(new MainView());
}
}
Вы конечно заметили, что закомментированы строки загрузки с репозиторием, который читает и сохраняет в XML файл, ну если все работает с хранилищем в памяти, осталось написать класс репозитория работающего с XML файлом и переключить использование на него в Program.cs. Вот он
public class PersonXmlRepository : IPersonRepository
{
private readonly string _path;
private List<Person> _people;
//ctor
public PersonXmlRepository(string path)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentException(nameof(path));
_path = path;
_people = new List<Person>();
}
/// <summary>
/// Запись в XML файл
/// </summary>
private void WriteFile()
{
var serializer = new XmlSerializer(typeof(List<Person>));
using (var writer = new StreamWriter(_path, false))
{
serializer.Serialize(writer, _people);
}
}
/// <summary>
/// Чтение из XML файла
/// </summary>
private void ReadFile()
{
var contents = String.Empty;
if (File.Exists(_path))
{
contents = File.ReadAllText(_path);
}
if (String.IsNullOrEmpty(contents))
{
return;
}
var serializer = new XmlSerializer(typeof(List<Person>));
using (var reader = new StringReader(contents))
{
var records = (List<Person>)serializer.Deserialize(reader);
_people.Clear();
_people.AddRange(records);
}
}
/// <summary>
/// Добавление нового человека
/// </summary>
/// <param name="person"></param>
/// <returns></returns>
public async Task<bool> AddPerson(Person person)
{
if (person == null)
throw new ArgumentNullException(nameof(person));
if (person.Id != 0)
throw new ArgumentException(nameof(person));
//назначаем Id
if (_people.Count == 0)
{
person.Id = 1;
}
else
{
person.Id = _people.Max(p => p.Id) + 1;
}
//добавляем в коллекцию
_people.Add(person);
//пишем в файл
try
{
await Task.Run(() => WriteFile());
}
catch (Exception ex)
{
Debug.WriteLine($"Ошибка {ex.Message} записи файла {_path}");
return false;
}
return true;
}
/// <summary>
/// Получение всей коллекции людей
/// </summary>
/// <returns></returns>
public async Task<List<Person>> GetPeople()
{
try
{
await Task.Run(() => ReadFile());
}
catch (Exception ex)
{
Debug.WriteLine($"Ошибка {ex.Message} чтения файла {_path}");
}
return _people;
}
}
Весь пример целиком здесь.
Имеется базовый класс для формы и собственно форма, которая его наследует:
Подскажите, пожалуйста, как посчитать количество итераций цикла do while с помощью Roslyn? Нужен семантический анализатор, который бы определял...
Для статических файлов в проекте ASPNET Core MVC есть папка wwwroot
Я хочу реализовать выстрел из гарпуна(хука), как в игре Dota 2Чтобы когда Pudge бросал крюк: 1