DepartmentProject/DepartmentPortal/Common/DesktopTools/Controls/AbstractGenericControlEntityList.cs

382 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 abstract partial class AbstractGenericControlEntityList<G, S, L, E, BL> : AbstractControlViewEntityList
where G : GetBindingModel, new()
where S : SetBindingModel, new()
where L : ListViewModel<E>
where E : ElementViewModel
where BL : GenericBusinessLogic<G, S, L, E>
{
/// <summary>
/// Объект бизнес-логики для получения данных
/// </summary>
protected BL _businessLogic;
/// <summary>
/// Констркутор
/// </summary>
public AbstractGenericControlEntityList()
{
InitializeComponent();
InitEvents();
_businessLogic = DependencyManager.Instance.Resolve<BL>();
}
public override async void Open()
{
if (dataGridViewList.Columns.Count == 0)
{
Configurate(GetConfig());
}
await LoadListAsync();
}
public override string GetTitleFromId(Guid id) => _businessLogic.GetElement(new G { Id = id })?.ToString();
/// <summary>
/// Конфигуратор контрола
/// </summary>
/// <param name="model">Настройки</param>
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<ViewModelOnListPropertyAttribute>();
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;
}
// при вызове контрола для выбора элемента, делаем возможность выбора только одной записи
dataGridViewList.MultiSelect = FormForSelected == null;
}
/// <summary>
/// Инициализация событий к контролам
/// </summary>
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) =>
{
if (FormForSelected != null && dataGridViewList.SelectedRows.Count > 0)
{
SelectedId = new Guid(dataGridViewList.SelectedRows[0].Cells[0].Value.ToString());
SelectedText = _businessLogic.GetElement(new G { Id = SelectedId })?.ToString();
FormForSelected.DialogResult = DialogResult.OK;
FormForSelected.Close();
return;
}
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(); };
}
/// <summary>
/// Вызов события загрузки данных на datagrid
/// </summary>
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;
}
}
/// <summary>
/// Заполнение таблицы
/// </summary>
/// <param name="data"></param>
private void FillDataOnGridAsync(List<E> data)
{
if (data == null)
{
return;
}
dataGridViewList.Rows.Clear();
foreach (var elem in data)
{
var mas = new List<object>();
foreach (DataGridViewColumn column in dataGridViewList.Columns)
{
mas.Add(elem.GetType().GetProperty(column.Name["Column".Length..])?.GetValue(elem));
}
dataGridViewList.Rows.Add(mas.ToArray());
}
}
/// <summary>
/// Вызов события при добавлении элемента
/// </summary>
private void CallAddElementEvent() => LaunchControl(null);
/// <summary>
/// Вызов события при изменении элемента
/// </summary>
private void CallUpdElementEvent()
{
foreach (DataGridViewRow selected in dataGridViewList.SelectedRows)
{
LaunchControl(new Guid(selected.Cells[0].Value.ToString()));
}
}
/// <summary>
/// Вызов события при удалении элемента
/// </summary>
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;
}
}
}
/// <summary>
/// Создание формы с контролом для работы с элементом
/// </summary>
/// <param name="id"></param>
private void LaunchControl(Guid? id)
{
try
{
var control = new GenericControlEntityElement<G, S, L, E, BL>();
control.Open(id);
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 abstract ControlViewEntityListConfiguration GetConfig();
protected abstract L GetData();
protected abstract L GetDataWithPageName(string key);
protected abstract L GetDataWithPageNumber(int page, int count);
}
}