using DesktopTools.Models; using ModuleTools.Attributes; using ModuleTools.BindingModels; using ModuleTools.BusinessLogics; using ModuleTools.Extensions; using ModuleTools.ViewModels; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using System.Windows.Forms; namespace DesktopTools.Controls { public partial class GenericControlEntityList : BaseControlViewEntityList where G : GetBindingModel, new() where S : SetBindingModel, new() where L : ListViewModel where E : ElementViewModel where BL : GenericBusinessLogic { /// /// Объект бизнес-логики для получения данных /// protected BL _businessLogic; /// /// Констркутор /// public GenericControlEntityList() { InitializeComponent(); InitEvents(); _businessLogic = DependencyManager.Instance.Resolve(); } public override async void Open() { base.Open(); if (dataGridViewList.Columns.Count == 0) { Configurate(GetConfig()); } await LoadListAsync(); } public override void Close() { base.Close(); } /// /// Конфигуратор контрола /// /// Настройки private void Configurate(ControlViewEntityListConfiguration config) { if (config == null) { return; } // формирование таблицы на основе модели dataGridViewList.Columns.Clear(); var properties = typeof(E).GetProperties(); foreach (var property in properties) { var attr = property.GetCustomAttribute(); if (attr != null) { var colIndex = attr.DisplayName == "Идентификатор" ? 0 : dataGridViewList.Columns.Count; dataGridViewList.Columns.Insert(colIndex, new DataGridViewTextBoxColumn { HeaderText = attr.DisplayName, Name = string.Format("Column{0}", property.Name), ReadOnly = true, Visible = !attr.IsHide, Width = attr.ColumnWidth ?? 0, AutoSizeMode = attr.ColumnWidth.HasValue ? DataGridViewAutoSizeColumnMode.None : DataGridViewAutoSizeColumnMode.Fill }); } } // настройка отображения основных кнопок if (config.ShowToolStripButton != null) { foreach (ToolStripItem button in toolStripMenu.Items) { if (config.ShowToolStripButton.Contains(button.Name)) { button.Visible = false; switch (button.Name) { case "toolStripButtonUpd": toolStripSeparator1.Visible = false; break; case "toolStripButtonDel": toolStripSeparator2.Visible = false; break; case "toolStripButtonRef": toolStripSeparator3.Visible = false; break; case "toolStripButtonSearch": toolStripSeparator4.Visible = false; break; } } } } // Загрузка подпунктов в контекстное меню и в пункт меню "Действие" if (config.ControlOnMoveElem != null) { foreach (var elem in config.ControlOnMoveElem) { ToolStripMenuItem item = new() { Text = elem.Value.Title, Name = elem.Key }; item.Click += elem.Value.Event; toolStripSplitButtonActions.DropDownItems.Add(item); contextMenuStripDataGrid.Items.Add(item); } } // либо скрытие пункта, если не предусмотренно подпунктов else { toolStripSplitButtonActions.Visible = false; toolStripSeparator3.Visible = false; } // Пагинация if (config.PaginationOn) { if (config.CountElementsOnPage.HasValue) { toolStripTextBoxPage.Tag = config.CountElementsOnPage.Value; } // пагинация по названиям if (config.PageNamesForPagination != null) { toolStripButtonPrev.Visible = toolStripLabelPage.Visible = toolStripTextBoxPage.Visible = toolStripLabelCountPages.Visible = toolStripButtonNext.Visible = false; toolStripComboBoxPageNames.Items.AddRange(config.PageNamesForPagination.ToArray()); toolStripComboBoxPageNames.SelectedIndex = 0; } // пагинация по страницам else { toolStripLabelPageName.Visible = toolStripComboBoxPageNames.Visible = false; } } // нет пагинации else { toolStripFooter.Visible = false; } } /// /// Инициализация событий к контролам /// private void InitEvents() { toolStripButtonAdd.Click += (object sender, EventArgs e) => { CallAddElementEvent(); }; toolStripButtonUpd.Click += (object sender, EventArgs e) => { CallUpdElementEvent(); }; toolStripButtonDel.Click += (object sender, EventArgs e) => { CallDelElementEvent(); }; toolStripButtonSearch.Click += (object sender, EventArgs e) => { panelSearch.Visible = !panelSearch.Visible; }; toolStripButtonRef.Click += async (object sender, EventArgs e) => { await LoadListAsync(); }; toolStripButtonClose.Click += (object sender, EventArgs e) => { Close(); }; buttonSearch.Click += async (object sender, EventArgs e) => { await LoadListAsync(); }; buttonCancelSearch.Click += (object sender, EventArgs e) => { panelSearch.Visible = false; }; dataGridViewList.KeyDown += (object sender, KeyEventArgs e) => { switch (e.KeyCode) { case Keys.Insert: CallAddElementEvent(); break; case Keys.Enter: CallUpdElementEvent(); break; case Keys.Delete: CallDelElementEvent(); break; } }; dataGridViewList.CellDoubleClick += (object sender, DataGridViewCellEventArgs e) => { CallUpdElementEvent(); }; toolStripButtonPrev.Click += async (object sender, EventArgs e) => { if (int.TryParse(toolStripTextBoxPage.Text, out int page)) { toolStripTextBoxPage.Text = (page - 1).ToString(); await LoadListAsync(); } }; toolStripButtonNext.Click += async (object sender, EventArgs e) => { if (int.TryParse(toolStripTextBoxPage.Text, out int page)) { toolStripTextBoxPage.Text = (page + 1).ToString(); await LoadListAsync(); } }; toolStripTextBoxPage.KeyDown += async (object sender, KeyEventArgs e) => { if (e.KeyData == Keys.Enter) { await LoadListAsync(); } }; toolStripComboBoxPageNames.SelectedIndexChanged += async (object sender, EventArgs e) => { await LoadListAsync(); }; } /// /// Вызов события загрузки данных на datagrid /// private async Task LoadListAsync() { var cursor = Cursor.Current; L data = null; try { Cursor.Current = Cursors.WaitCursor; // если включена пагинация if (toolStripFooter.Visible) { // постраничная if (toolStripTextBoxPage.Visible) { if (int.TryParse(toolStripTextBoxPage.Text, out int page) && int.TryParse(toolStripTextBoxPage.Tag.ToString(), out int count)) { await Task.Run(() => data = GetDataWithPageNumber(page, count)); } } // поименная else if (toolStripComboBoxPageNames.Visible) { var key = toolStripComboBoxPageNames.Text; if (key.IsNotEmpty()) { await Task.Run(() => data = GetDataWithPageName(key)); } } } else { await Task.Run(() => data = GetData()); } if (data == null) { // TODO вывод сообщения об ощибок return; } toolStripLabelCountPages.Text = $"из {data.MaxCount}"; FillDataOnGridAsync(data.List); } finally { Cursor.Current = cursor; } } /// /// Заполнение таблицы /// /// private void FillDataOnGridAsync(List data) { if (data == null) { return; } dataGridViewList.Rows.Clear(); foreach (var elem in data) { var mas = new List(); foreach (DataGridViewColumn column in dataGridViewList.Columns) { mas.Add(elem.GetType().GetProperty(column.Name["Column".Length..])?.GetValue(elem)); } dataGridViewList.Rows.Add(mas.ToArray()); } } /// /// Вызов события при добавлении элемента /// private void CallAddElementEvent() => LaunchControl(null); /// /// Вызов события при изменении элемента /// private void CallUpdElementEvent() { foreach (DataGridViewRow selected in dataGridViewList.SelectedRows) { LaunchControl(new Guid(selected.Cells[0].Value.ToString())); } } /// /// Вызов события при удалении элемента /// private void CallDelElementEvent() { if (MessageBox.Show("Удалить выбранные записи?", "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { var cursor = Cursor.Current; try { Cursor.Current = Cursors.WaitCursor; foreach (DataGridViewRow selected in dataGridViewList.SelectedRows) { _businessLogic.Delete(new G { Id = new Guid(selected.Cells[0].Value.ToString()) }); } } catch (Exception ex) { if (_businessLogic.Errors.Count != 0) { MessageBox.Show(_businessLogic.Errors.LastOrDefault().Message ?? ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { Cursor.Current = cursor; } } } /// /// Создание формы с контролом для работы с элементом /// /// private void LaunchControl(Guid? id) { try { var control = new GenericControlEntityElement(id); control.Open(); var form = new Form { Height = control.Height, Width = control.Width, Text = $"{Title}. Добавление", StartPosition = FormStartPosition.CenterParent, ControlBox = false }; form.Controls.Add(control); control.Dock = DockStyle.Fill; control.Form = form; form.Show(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } protected virtual ControlViewEntityListConfiguration GetConfig() => new(); protected virtual L GetData() { return null; } protected virtual L GetDataWithPageName(string key) { return null; } protected virtual L GetDataWithPageNumber(int page, int count) { return null; } } }