Есть две формы, на одной отображаются данные в таблице на другой они добавляются. Надо что бы после нажатия сохранить на второй форме, внесенные данные отображались в таблице на первой форме. Можно конечно добавить на первую таблицу таймер который будет в случае изменений в таблице ее перестраивать. Но может вы подскажите более правильное решение.
Создадим класс модели данных с поддержкой IDataErrorInfo
для работы ErrorProvider
в форме
public class Person : IDataErrorInfo
{
public int OrderNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
#region Реализация IDataErrorInfo
public string _Error;
public string Error => _Error;
public string this[string columnName] => CheckProperties(columnName);
/// <summary>
/// Проверка значений свойств на валидность
/// </summary>
/// <param name="columnName">имя проверяемого свойства</param>
/// <returns>строка с описанием ошибки</returns>
private string CheckProperties(string columnName)
{
if (columnName.Equals(nameof(FirstName)) && String.IsNullOrEmpty(FirstName))
{
_Error = "Укажите имя";
return _Error;
}
if (columnName.Equals(nameof(FirstName)) && FirstName?.Trim().Length < 2)
{
_Error = "Имя не может быть короче двух символов";
return _Error;
}
if (columnName.Equals(nameof(LastName)) && String.IsNullOrEmpty(LastName))
{
_Error = "Укажите фамилию";
return _Error;
}
if (columnName.Equals(nameof(LastName)) && LastName?.Trim().Length < 2)
{
_Error = "Фамилия не может быть короче двух символов";
return _Error;
}
_Error = String.Empty;
return _Error;
}
#endregion
/// <summary>
/// Валиден ли данный чел.
/// </summary>
/// <returns></returns>
public bool IsValid()
{
var errorFN = this["FirstName"];
var errorLN = this["LastName"];
_Error = errorFN + " " + errorLN;
return String.IsNullOrWhiteSpace(Error);
}
}
Форма ввода данных, в ней мы объявляем событие DataEntered
, с помощью которого будем оповещать главную форму о том, что данные готовы, и их можно забрать
public partial class FormInput : Form
{
//редактируемая модель
private readonly Person _person;
//событие готовности данных для чтения FormMain
public EventHandler DataEntered;
public FormInput()
{
InitializeComponent();
_person = new Person();
_buttonSave.Click += ButtonSave_Click;
this.Load += FormInput_Load;
}
private void FormInput_Load(object sender, EventArgs e)
{
//привязки свойств модели к текстбоксам
_textBoxFirstName.DataBindings.Add("Text", _person, nameof(_person.FirstName),
true, DataSourceUpdateMode.OnPropertyChanged);
_textBoxLastName.DataBindings.Add("Text", _person, nameof(_person.LastName),
true, DataSourceUpdateMode.OnPropertyChanged);
//привязка ErrorProvider для отображения ошибок ввода
_errorProvider.DataSource = _person;
}
private void ButtonSave_Click(object sender, EventArgs e)
{
//проверяем введенные данные на валидность
if (!_person.IsValid())
{
var message = $"Не все данные введены верно!\n{_person.Error}";
var caption = "Предупреждение";
MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//данные валидные значит вызываем событие для оповещения FormMain
DataEntered?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Получение чела для вставки в DGV
/// </summary>
/// <param name="number">назначаемый порядковый номер</param>
/// <returns>экземпляр Person</returns>
public Person GetPerson(int number)
{
//создаем нового чела для передачи
var result = new Person
{
OrderNumber = number,
FirstName = new string(_person.FirstName.Trim().ToCharArray()),
LastName = new string(_person.LastName.Trim().ToCharArray()),
};
//поля ввода очищаем
_textBoxFirstName.Text = String.Empty;
_textBoxLastName.Text = String.Empty;
_textBoxFirstName.Focus();
return result;
}
}
Главная форма, с формой ввода работаем через событие
public partial class FormMain : Form
{
//ссылка на форму ввода данных
private FormInput _inputForm;
//источник данных для DGV
private readonly BindingSource _bsPeople;
public FormMain()
{
InitializeComponent();
_bsPeople = new BindingSource();
_buttonOpenInput.Click += ButtonOpenInput_Click;
this.Load += FormMain_Load;
}
private void FormMain_Load(object sender, EventArgs e)
{
_bsPeople.DataSource = typeof(List<Person>);
//привязка к данным DGV
_dataGridView.AutoGenerateColumns = false;
_dataGridView.DataSource = _bsPeople;
//привязка свойств модели к колонкам DGV
_columnOrderNumber.DataPropertyName = nameof(Person.OrderNumber);
_columnLastName.DataPropertyName = nameof(Person.LastName);
_columnFirstName.DataPropertyName = nameof(Person.FirstName);
}
/// <summary>
/// Кнопка Добавить
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonOpenInput_Click(object sender, EventArgs e)
{
if (_inputForm != null)
return;
_inputForm = new FormInput();
_inputForm.Owner = this;
//подписываемся на событие готовности данных
_inputForm.DataEntered += FormInput_DataEntered;
_inputForm.FormClosed += InputForm_FormClosed;
//отображаем форму
_inputForm.Show();
}
/// <summary>
/// Обработчик события готовности данных в FormInput
/// Здесь мы извлекаем данные и вносим их в DGV
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormInput_DataEntered(object sender, EventArgs e)
{
//вычисляем порядковый номер для след.чела
int number = _bsPeople.Count + 1;
//добавляем в DGV нового чела
_bsPeople.Add(_inputForm.GetPerson(number));
}
/// <summary>
/// Обработчик события закрытия формы ввода
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void InputForm_FormClosed(object sender, FormClosedEventArgs e)
{
_inputForm = null;
}
}
Пример целиком здесь.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Согласно моему познанию ASPNET Core и если сильно не углубляться в детали, то на сегодняшний день обработка HTTP-запросов на одноядерном процессоре...
У меня есть generic метод преобразующий IQueryable<T> и возвращающий IOrderedQuerable<T> при помощи Linq-to-Entities
Пытаюсь как тут добавить ReactJS к проекту, но при добавлении этой строки:
У меня есть несколько скриптов, в одном выполняется в Awake парсинг xml, и значения заносятся в Dictionary, а в других выполняется получение значения...