DepartmentProject/DepartmentPortal/Common/ToolsDesktop/MainControls/GenericControlEntityList.cs

636 lines
20 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml.Linq;
using ToolsDesktop.Enums;
using ToolsDesktop.Helpers;
using ToolsDesktop.Interfaces;
using ToolsDesktop.Models;
using ToolsModule.ManagmentDependency;
using ToolsModule.ManagmentEntity;
using ToolsModule.ManagmentExtension;
using ToolsModule.ManagmentSecurity;
namespace ToolsDesktop.Controls
{
public partial class GenericControlEntityList<G, S, L, E, BL> : MainControlViewEntityList, IControlViewEntityList
where G : GetBindingModel, new()
where S : SetBindingModel, new()
where L : ListViewModel<E>
where E : ElementViewModel
where BL : IGenericEntityLogic<G, S, L, E>
{
/// <summary>
/// Режим работы
/// </summary>
private ControlOpenMode _openMode;
/// <summary>
/// Событие, вызываемое при закрытии контрола
/// </summary>
private event Action<Guid> CloseListEvent;
/// <summary>
/// Событие, вызываемое при закрытии контрола
/// </summary>
private event Action<bool> CloseSelectEvent;
private readonly object _lockObject = new();
private bool _usePages = false;
private bool _useNames = false;
/// <summary>
/// Объект бизнес-логики для получения данных
/// </summary>
protected BL _businessLogic;
/// <summary>
/// Методы для реализации в generic-контроле
/// </summary>
protected IGenericControlEntityList _genericControlViewEntityList;
/// <summary>
/// Констркутор
/// </summary>
public GenericControlEntityList()
{
InitializeComponent();
InitEvents();
_businessLogic = DependencyManager.Instance.Resolve<BL>();
_controlViewEntityList = this;
}
#region IControlViewEntityList
public void OpenControl(ControlOpenModel model)
{
_openMode = model.OpenMode;
if (model.CloseList != null)
{
CloseListEvent += model.CloseList;
}
if (model.CloseSelect != null)
{
CloseSelectEvent += model.CloseSelect;
}
if (dataGridViewList.Columns.Count == 0)
{
try
{
Configurate(GetConfig());
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, $"{Title}. Ошибка при конфигурации");
}
}
if (!model.LazyLoading)
{
LoadList();
}
}
public IControl GetInstanceControl() => _genericControlViewEntityList?.GetInstanceGenericControl();
public string GetTitleFromIdControl(Guid id) => _businessLogic.GetElement(new G { Id = id })?.ToString();
public string SaveControlToXml() => new XElement("Control",
new XAttribute("Type", GetType().FullName),
new XAttribute("ControlId", ControlId),
new XAttribute("Title", Title),
new XAttribute("AccessOperation", AccessOperation),
new XElement("Configurate",
new XElement("Page", toolStripTextBoxPage.Text),
new XElement("CountElementsOnPage", toolStripTextBoxCountRecords.Text),
new XElement("PageName",
new XElement("Key", ((toolStripComboBoxPageNames.SelectedItem as PageNamesForPaginationModel)?.Key ?? "-")),
new XElement("Value", ((toolStripComboBoxPageNames.SelectedItem as PageNamesForPaginationModel)?.Value ?? "-"))),
new XElement("ParentId", ParentId?.ToString() ?? "-"))).ToString();
public void LoadControlFromXml(string xml)
{
var control = XElement.Parse(xml);
ControlId = new Guid(control.Attribute("ControlId").Value.ToString());
Title = control.Attribute("Title").Value.ToString();
AccessOperation = (AccessOperation)Enum.Parse(typeof(AccessOperation), control.Attribute("AccessOperation").Value.ToString());
var config = control.Element("Configurate");
toolStripTextBoxPage.Text = config.Element("Page").Value.ToString();
toolStripTextBoxCountRecords.Text = config.Element("CountElementsOnPage").Value.ToString();
if (config.Element("PageName").Element("Key").Value.ToString() != "-")
{
var pageName = new PageNamesForPaginationModel
{
Key = config.Element("PageName").Element("Key").Value.ToString(),
Value = config.Element("PageName").Element("Value").Value.ToString()
};
var elem = toolStripComboBoxPageNames.Items.Cast<PageNamesForPaginationModel>().FirstOrDefault(x => x.Key == pageName.Key);
if (elem != null)
{
toolStripComboBoxPageNames.SelectedIndexChanged -= ToolStripComboBoxPageNamesSelectedIndexChanged;
toolStripComboBoxPageNames.SelectedItem = elem;
toolStripComboBoxPageNames.SelectedIndexChanged += ToolStripComboBoxPageNamesSelectedIndexChanged;
}
}
if (config.Element("ParentId").Value.ToString() != "-")
{
ParentId = new Guid(config.Element("ParentId").Value.ToString());
}
LoadList();
}
#endregion
/// <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<ViewModelControlListPropertyAttribute>();
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,
AutoSizeMode = attr.ColumnWidth != 0 ? DataGridViewAutoSizeColumnMode.None : DataGridViewAutoSizeColumnMode.Fill
});
if (attr.DefaultCellStyleFormat.IsNotEmpty())
{
dataGridViewList.Columns[colIndex].DefaultCellStyle.Format = attr.DefaultCellStyleFormat;
}
}
}
labelTitle.Text = Title;
// настройка отображения основных кнопок
if (config.HideToolStripButton != null)
{
foreach (var elem in config.HideToolStripButton)
{
var ctrl = toolStripMenu.Items.Find(elem.ToString(), false);
if (ctrl != null && ctrl.Length > 0)
{
ctrl[0].Visible = false;
switch (elem)
{
case ToolStripButtonListNames.toolStripButtonAdd:
toolStripSeparator1.Visible = false;
break;
case ToolStripButtonListNames.toolStripButtonUpd:
toolStripSeparator2.Visible = false;
break;
case ToolStripButtonListNames.toolStripButtonDel:
toolStripSeparator3.Visible = false;
break;
case ToolStripButtonListNames.toolStripButtonSearch:
toolStripSeparator4.Visible = false;
break;
case ToolStripButtonListNames.toolStripButtonRef:
toolStripSeparator5.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);
ToolStripMenuItem itemContext = new() { Text = elem.Value.Title, Name = elem.Key };
itemContext.Click += elem.Value.Event;
contextMenuStripDataGrid.Items.Add(itemContext);
}
}
// либо скрытие пункта, если не предусмотренно подпунктов
else
{
toolStripSplitButtonActions.Visible = false;
toolStripSeparator5.Visible = false;
}
toolStripFooter.Visible = config.PaginationOn;
// Пагинация
if (config.PaginationOn)
{
// пагинация по страницам
if (config.CountElementsOnPage.HasValue)
{
_usePages = true;
toolStripTextBoxCountRecords.Text = config.CountElementsOnPage.Value.ToString();
toolStripLabelPageName.Visible = toolStripComboBoxPageNames.Visible = false;
}
// пагинация по названиям
if (config.PageNamesForPagination != null)
{
_useNames = true;
toolStripButtonPrev.Visible = toolStripLabelPage.Visible = toolStripTextBoxPage.Visible = toolStripLabelCountPages.Visible =
toolStripLabelCountRecords.Visible = toolStripTextBoxCountRecords.Visible = toolStripButtonNext.Visible = false;
toolStripComboBoxPageNames.Items.AddRange(config.PageNamesForPagination.ToArray());
if (toolStripComboBoxPageNames.Items.Count > 0)
{
toolStripComboBoxPageNames.SelectedIndexChanged -= ToolStripComboBoxPageNamesSelectedIndexChanged;
toolStripComboBoxPageNames.SelectedIndex = 0;
toolStripComboBoxPageNames.SelectedIndexChanged += ToolStripComboBoxPageNamesSelectedIndexChanged;
}
toolStripComboBoxPageNames.Tag = config.ParentPropertyName;
}
}
// при вызове контрола для выбора элемента, делаем возможность выбора только одной записи
dataGridViewList.MultiSelect = _openMode == ControlOpenMode.List;
// Открытие через родительский элемент
if (_openMode == ControlOpenMode.Child)
{
panelHeader.Visible = false;
toolStripButtonClose.Visible = false;
toolStripSeparator6.Visible = false;
toolStripButtonSelect.Visible = false;
}
// Открытие через родительский элемент
if (_openMode == ControlOpenMode.Select)
{
toolStripSeparator6.Visible = true;
toolStripButtonSelect.Visible = true;
}
Dock = DockStyle.Fill;
}
/// <summary>
/// Инициализация событий к контролам
/// </summary>
private void InitEvents()
{
toolStripButtonAdd.Click += (object sender, EventArgs e) => { AddElement(); };
toolStripButtonUpd.Click += (object sender, EventArgs e) => { UpdElement(); };
toolStripButtonDel.Click += (object sender, EventArgs e) => { DelElement(); };
toolStripButtonSearch.Click += (object sender, EventArgs e) => { panelSearch.Visible = !panelSearch.Visible; };
toolStripButtonRef.Click += (object sender, EventArgs e) => { LoadList(); };
toolStripButtonSelect.Click += (object sender, EventArgs e) => { SelectElement(); };
toolStripButtonClose.Click += (object sender, EventArgs e) =>
{
CloseListEvent?.Invoke(ControlId);
CloseSelectEvent?.Invoke(false);
Dispose();
};
buttonSearch.Click += (object sender, EventArgs e) => { LoadList(); };
buttonCancelSearch.Click += (object sender, EventArgs e) => { panelSearch.Visible = false; LoadList(); };
dataGridViewList.KeyDown += (object sender, KeyEventArgs e) =>
{
switch (e.KeyCode)
{
case Keys.Insert:
if (toolStripButtonAdd.Visible)
{
AddElement();
}
break;
case Keys.Enter:
if (toolStripButtonUpd.Visible)
{
UpdElement();
}
break;
case Keys.Delete:
if (toolStripButtonDel.Visible)
{
DelElement();
}
break;
}
};
dataGridViewList.CellDoubleClick += (object sender, DataGridViewCellEventArgs e) =>
{
if (_openMode == ControlOpenMode.Select && dataGridViewList.SelectedRows.Count > 0)
{
SelectElement();
}
UpdElement();
};
toolStripButtonPrev.Click += (object sender, EventArgs e) =>
{
if (int.TryParse(toolStripTextBoxPage.Text, out int page))
{
toolStripTextBoxPage.Text = (page - 1).ToString();
LoadList();
}
};
toolStripButtonNext.Click += (object sender, EventArgs e) =>
{
if (int.TryParse(toolStripTextBoxPage.Text, out int page))
{
toolStripTextBoxPage.Text = (page + 1).ToString();
LoadList();
}
};
toolStripTextBoxPage.KeyDown += (object sender, KeyEventArgs e) =>
{
if (e.KeyData == Keys.Enter)
{
LoadList();
}
};
toolStripComboBoxPageNames.SelectedIndexChanged += ToolStripComboBoxPageNamesSelectedIndexChanged;
}
/// <summary>
/// Событие смены выбрарнного элемента выпдающего спика (вынесено отдельно, чтобы при настройки конфигурации не вызывать прогрузку)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ToolStripComboBoxPageNamesSelectedIndexChanged(object sender, EventArgs e) => LoadList();
/// <summary>
/// Вызов события загрузки данных на datagrid
/// </summary>
private void LoadList()
{
var cursor = Cursor.Current;
var selectedGuids = new List<Guid>();
foreach (DataGridViewRow row in dataGridViewList.SelectedRows)
{
selectedGuids.Add(new Guid(row.Cells[0].Value.ToString()));
}
L data = null;
try
{
Cursor.Current = Cursors.WaitCursor;
var model = new G();
if (panelSearch.Visible)
{
var controls = panelSearchControls.Controls.Cast<IBaseControl>();
foreach (var cntrl in controls)
{
var prop = typeof(G).GetProperty(cntrl.GetPropertyName());
if (prop != null)
{
prop.SetValue(model, cntrl.GetValueFromControl());
}
}
}
if (ParentPropertyName.IsNotEmpty())
{
if (ParentId.HasValue)
{
var prop = typeof(G).GetProperty(ParentPropertyName);
if (prop != null)
{
prop.SetValue(model, ParentId);
}
Visible = true;
}
else
{
Visible = false;
}
}
// если включена пагинация
// постраничная
if (_usePages)
{
if (int.TryParse(toolStripTextBoxPage.Text, out int page) && int.TryParse(toolStripTextBoxCountRecords.Text.ToString(), out int count))
{
model.PageNumber = page - 1;
model.PageSize = count;
}
}
// поименная
if (_useNames)
{
if (toolStripComboBoxPageNames.SelectedItem is PageNamesForPaginationModel key)
{
var prop = typeof(G).GetProperty(toolStripComboBoxPageNames.Tag.ToString());
if (prop != null)
{
prop.SetValue(model, key.Key);
}
}
}
data = _businessLogic.GetList(model);
if (data == null && _businessLogic.Errors.Count > 0)
{
DialogHelper.MessageException(_businessLogic.Errors, $"{Title}. Ошибки при получении данных");
return;
}
toolStripLabelCountPages.Text = $"из {data?.MaxCount}";
}
catch (Exception ex)
{
if (_businessLogic.Errors.Count > 0)
{
DialogHelper.MessageException(_businessLogic.Errors, $"{Title}. Ошибки при получении данных");
}
else
{
DialogHelper.MessageException(ex.Message, $"{Title}. Ошибка при получении данных");
}
}
finally
{
Cursor.Current = cursor;
}
FillDataOnGrid(data?.List, selectedGuids);
}
/// <summary>
/// Заполнение таблицы
/// </summary>
/// <param name="data"></param>
private void FillDataOnGrid(List<E> data, List<Guid> selectedGuids)
{
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());
dataGridViewList.Rows[^1].Selected = selectedGuids.Contains(new Guid(mas[0].ToString()));
}
if (selectedGuids.Count == 0 && dataGridViewList.Rows.Count > 0)
{
dataGridViewList.Rows[0].Selected = true;
}
}
/// <summary>
/// Вызов события при добавлении элемента
/// </summary>
private void AddElement() => LaunchControl(null);
/// <summary>
/// Вызов события при изменении элемента
/// </summary>
private void UpdElement()
{
foreach (DataGridViewRow selected in dataGridViewList.SelectedRows)
{
LaunchControl(new Guid(selected.Cells[0].Value.ToString()));
}
}
/// <summary>
/// Вызов события при удалении элемента
/// </summary>
private void DelElement()
{
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)
{
DialogHelper.MessageException(_businessLogic.Errors, $"{Title}. Ошибки при удалении");
}
else
{
DialogHelper.MessageException(ex.Message, $"{Title}. Ошибки при удалении");
}
}
finally
{
Cursor.Current = cursor;
LoadList();
}
}
}
/// <summary>
/// Вызов события при выборе элемента
/// </summary>
private void SelectElement()
{
try
{
SelectedId = new Guid(dataGridViewList.SelectedRows[0].Cells[0].Value.ToString());
SelectedText = _businessLogic.GetElement(new G { Id = SelectedId })?.ToString();
CloseSelectEvent?.Invoke(true);
Dispose();
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, $"{Title}. Ошибка при получении выбранного значения");
}
}
/// <summary>
/// Создание формы с контролом для работы с элементом
/// </summary>
/// <param name="id"></param>
private void LaunchControl(Guid? id)
{
try
{
var control = ControlViewEntityElement.GetInstance() as IControlChildEntity;
if (ParentId.HasValue)
{
control.ParentId = ParentId;
control.ParentPropertyName = ParentPropertyName;
}
else if (toolStripFooter.Visible && toolStripComboBoxPageNames.Visible)
{
if (toolStripComboBoxPageNames.SelectedItem is PageNamesForPaginationModel key)
{
if (key.Key.GetType().Name == "Guid")
{
control.ParentId = new Guid(key.Key.ToString());
}
control.ParentPropertyName = toolStripComboBoxPageNames.Tag?.ToString();
}
}
var form = new Form
{
Text = (id.HasValue ? $"{Title}. Редактирование" : $"{Title}. Добавление"),
StartPosition = FormStartPosition.CenterScreen,
ControlBox = false
};
control.Open(new ControlOpenModel
{
OpenMode = ControlOpenMode.List,
ElementId = id,
CloseElement = (Guid id) =>
{
LoadList();
form.Close();
}
});
form.Height = (control as UserControl).Height + 55;
form.Width = (control as UserControl).Width + 20;
form.Controls.Add(control as UserControl);
form.Show();
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, $"{Title}. Ошибки при открытии элемента");
}
}
/// <summary>
/// Получение настроек для контрола
/// </summary>
/// <returns></returns>
private ControlViewEntityListConfiguration GetConfig() => _genericControlViewEntityList?.GetConfigControl();
/// <summary>
/// Получение списка идентификаторов выбранных записей
/// </summary>
/// <returns></returns>
protected List<Guid> GetSelectedIds()
{
List<Guid> guids = new();
foreach (DataGridViewRow selected in dataGridViewList.SelectedRows)
{
guids.Add(new Guid(selected.Cells[0].Value.ToString()));
}
return guids;
}
}
}