DepartmentProject/DepartmentPortal/Common/DesktopTools/MainControls/GenericControlEntityElement.cs

369 lines
11 KiB
C#
Raw Normal View History

using DesktopTools.BaseControls;
using DesktopTools.Enums;
using DesktopTools.Helpers;
using DesktopTools.Interfaces;
using DesktopTools.Models;
using ModuleTools.Attributes;
using ModuleTools.BindingModels;
using ModuleTools.BusinessLogics;
using ModuleTools.Enums;
using ModuleTools.Extensions;
using ModuleTools.ViewModels;
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml.Linq;
namespace DesktopTools.Controls
{
public partial class GenericControlEntityElement<G, S, L, E, BL> : MainControlViewEntityElement, IControlViewEntityElement
where G : GetBindingModel, new()
where S : SetBindingModel, new()
where L : ListViewModel<E>
where E : ElementViewModel
where BL : GenericBusinessLogic<G, S, L, E>
{
/// <summary>
/// Объект бизнес-логики для получения данных
/// </summary>
private readonly BL _businessLogic;
/// <summary>
/// Методы для реализации в generic-контроле
/// </summary>
protected IGenericControlEntityElement _genericControlViewEntityElement;
/// <summary>
/// Признак налиичия изменений
/// </summary>
private bool _haveChages = false;
/// <summary>
/// Ширина контрола по умолчанию
/// </summary>
private readonly int _defaultControlWidth = 350;
private E _element = null;
/// <summary>
/// Событие, вызываемое при закрытии контрола
/// </summary>
private event Action<Guid> CloseElementEvent;
/// <summary>
/// События установки одинаковой ширины для заголовков контролов
/// </summary>
private event Action<int> SetTitleWidth;
/// <summary>
/// Событие установки значения
/// </summary>
private event Action<object> SetValues;
/// <summary>
/// Событие сброса значения в исходное состояние
/// </summary>
private event Action DropValues;
/// <summary>
/// Событие проверки заполненности контрола
/// </summary>
private event Func<bool> CheckValues;
/// <summary>
/// Событие получения значения из контрола
/// </summary>
private event Action<object> GetValues;
private E Element
{
get { return _element; }
set
{
try
{
_element = value;
SetValues?.Invoke(_element);
if (tabControl.Visible)
{
foreach (TabPage page in tabControl.TabPages)
{
if (page.Name == tabPageMain.Name)
{
continue;
}
if (page.Controls[0] is IControlChildEntity cntrl)
{
cntrl.ParentId = _element.Id;
cntrl.Open(new ControlOpenModel { OpenMode = ControlOpenMode.Child });
}
}
}
_haveChages = false;
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при установки значений");
}
}
}
public GenericControlEntityElement()
{
InitializeComponent();
InitEvents();
_businessLogic = DependencyManager.Instance.Resolve<BL>();
_controlViewEntityElement = this;
}
public void OpenControl(ControlOpenModel model)
{
if (model.CloseElement != null)
{
CloseElementEvent += model.CloseElement;
}
if (panelContainer.Controls.Count == 0)
{
try
{
Configurate();
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при конфигурации");
}
}
if (model.ElementId.HasValue)
{
Element = _businessLogic.GetElement(new G { Id = model.ElementId });
if (Element == null)
{
DialogHelper.MessageException(_businessLogic.Errors, "Ошибки при получении элемента");
}
}
Dock = DockStyle.Fill;
}
public IControl GetInstanceControl() => _genericControlViewEntityElement?.GetInstanceGenericControl();
public string SaveControlToXml() => new XElement("Control",
new XAttribute("Type", GetType().FullName),
new XAttribute("ControlId", ControlId),
new XAttribute("Title", Title)).ToString();
public void LoadControlFromXml(string xml)
{
var control = XElement.Parse(xml).Element("Control");
ControlId = new Guid(control.Attribute("ControlId").Value.ToString());
Title = control.Attribute("Title").Value.ToString();
}
private void InitEvents()
{
toolStripButtonSave.Click += (object sender, EventArgs e) => { Save(); };
toolStripButtonReload.Click += (object sender, EventArgs e) =>
{
if (DialogHelper.MessageQuestion("Отменить все внесенные изменения?") == DialogResult.Yes)
{
try
{
DropValues?.Invoke();
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при сбросе значений");
}
}
};
toolStripButtonClose.Click += (object sender, EventArgs e) => {
if (_haveChages && DialogHelper.MessageQuestion("Имеется несохраненные данные, вы действительно хотите закрыть элемент?", "Закрытие элемента") == DialogResult.Yes)
{
if (Save())
{
return;
}
}
CloseElementEvent?.Invoke(ControlId);
Dispose();
};
}
private void Configurate()
{
var attributeClass = typeof(E).GetCustomAttribute<ViewModelControlElementClassAttribute>();
if (attributeClass == null)
{
return;
}
tabControl.Visible = attributeClass.HaveDependenceEntities;
panelContainer.Visible = !attributeClass.HaveDependenceEntities;
Width = attributeClass.Width != 0 ? attributeClass.Width : _defaultControlWidth;
int positionY = 5;
int positionX = 5;
int interval = 15;
int titleWidth = 0;
foreach (var property in typeof(E).GetProperties())
{
var attribute = property.GetCustomAttribute<ViewModelControlElementPropertyAttribute>();
if (attribute != null)
{
AbstractBaseControl control = null;
switch (attribute.ControlType)
{
case ControlType.ControlString:
control = new BaseControlString(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MaxLength);
break;
case ControlType.ControlText:
control = new BaseControlText(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MaxLength, attribute.Height);
break;
case ControlType.ControlInt:
control = new BaseControlInt(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MinValue, attribute.MaxValue);
break;
case ControlType.ControlDecimal:
control = new BaseControlDecimal(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MinValue,
attribute.MaxValue, attribute.DecimalPlaces);
break;
case ControlType.ControlBool:
control = new BaseControlBool(property.Name, attribute.MustHaveValue, attribute.ReadOnly);
break;
case ControlType.ControlDateTime:
control = new BaseControlDateTime(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.MinDate,
attribute.MaxDate, attribute.CustomDateFormat);
break;
case ControlType.ControlImage:
control = new BaseControlImage(property.Name, attribute.MustHaveValue, attribute.ReadOnly, attribute.Width, attribute.Height);
break;
case ControlType.ControlEnum:
control = new BaseControlEnum(property.Name, attribute.MustHaveValue, attribute.ReadOnly, property.PropertyType);
break;
case ControlType.ControlGuid:
if (attribute.ControlTypeObject.IsNotEmpty())
{
control = new BaseControlGuid(property.Name, attribute.MustHaveValue, attribute.ReadOnly,
DependencyManager.Instance.Resolve(Type.GetType(attribute.ControlTypeObject)) as IControlEntitySelectable,
property.Name == ParentPropertyName ? ParentId : null);
}
break;
}
if (control == null)
{
continue;
}
var widthTitle = control.SetTitle(attribute.DisplayName);
if (widthTitle > titleWidth)
{
titleWidth = widthTitle;
}
control.OnValueChangeEvent += () => { _haveChages = true; };
SetValues += control.SetValue;
DropValues += control.DropValue;
CheckValues += control.CheckValue;
SetTitleWidth += control.SetTitleWidth;
GetValues += control.GetValue;
control.Location = new System.Drawing.Point(positionX, positionY);
control.Width = Width - positionX * 2 - (tabControl.Visible ? 10 : 0);
control.Anchor = AnchorStyles.Top | AnchorStyles.Left;
if (panelContainer.Visible)
{
control.Anchor |= AnchorStyles.Right;
}
positionY += control.Height + interval;
if (panelContainer.Visible)
{
panelContainer.Controls.Add(control);
}
if (tabControl.Visible)
{
tabPageMain.Controls.Add(control);
}
}
}
SetTitleWidth(titleWidth);
Height = attributeClass.Height != 0 ? attributeClass.Height : positionY;
if (attributeClass.HaveDependenceEntities)
{
var attrDependences = typeof(E).GetCustomAttributes<ViewModelControlElementDependenceEntityAttribute>();
if (attrDependences != null)
{
foreach (var attr in attrDependences)
{
if (DependencyManager.Instance.Resolve(Type.GetType(attr.ControlTypeObject)) is IControlChildEntity control)
{
var cntrl = control.GetInstance() as IControlChildEntity;
cntrl.ParentPropertyName = attr.ParentPropertyName;
//cntrl.Open(null);
var tabPage = new TabPage
{
Location = new System.Drawing.Point(4, 24),
Name = "tabPage",
Padding = new Padding(3),
Size = new System.Drawing.Size(122, 99),
TabIndex = 0,
Text = attr.Title,
UseVisualStyleBackColor = true
};
tabPage.Controls.Add(cntrl as UserControl);
tabControl.TabPages.Add(tabPage);
if (attr.IsActive)
{
tabPage.Select();
}
}
}
}
}
}
private bool Save()
{
if (CheckValues.GetInvocationList().Select(x => (bool)x.DynamicInvoke()).ToList().Any(x => !x))
{
return false;
}
var model = Element == null ? new S() : Mapper.MapToClass<E, S>(Element, true);
try
{
GetValues(model);
}
catch (Exception ex)
{
DialogHelper.MessageException(ex.Message, "Ошибка при получении значений");
}
if (model != null)
{
if (Element == null)
{
Element = _businessLogic.Create(model);
}
else
{
Element = _businessLogic.Update(model);
}
if (Element == null)
{
DialogHelper.MessageException(_businessLogic.Errors, "Ошибки при сохранении элемента");
}
_haveChages = false;
DialogHelper.MessageInformation("Сохранение прошло успешно", "Сообщение");
return true;
}
return false;
}
}
}