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.Collections.Generic; using System.Linq; using System.Reflection; using System.Windows.Forms; using System.Xml.Linq; namespace DesktopTools.Controls { public partial class GenericControlEntityElement : MainControlViewEntityElement, IControlViewEntityElement where G : GetBindingModel, new() where S : SetBindingModel, new() where L : ListViewModel where E : ElementViewModel where BL : GenericBusinessLogic { /// /// Объект бизнес-логики для получения данных /// private readonly BL _businessLogic; /// /// Методы для реализации в generic-контроле /// protected IGenericControlEntityElement _genericControlViewEntityElement; /// /// Признак налиичия изменений /// private bool _haveChages = false; /// /// Ширина контрола по умолчанию /// private readonly int _defaultControlWidth = 350; private E _element = null; /// /// Событие, вызываемое при закрытии контрола /// private event Action CloseElementEvent; /// /// События установки одинаковой ширины для заголовков контролов /// private event Action SetTitleWidth; /// /// Событие установки значения /// private event Action SetValues; /// /// Событие сброса значения в исходное состояние /// private event Action DropValues; /// /// Событие проверки заполненности контрола /// private event Func CheckValues; /// /// Событие получения значения из контрола /// private event Action GetValues; private E Element { get { return _element; } set { try { _element = value; if (_element != null) { 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, $"{Title}. Ошибка при установки значений"); } } } public GenericControlEntityElement() { InitializeComponent(); InitEvents(); _businessLogic = DependencyManager.Instance.Resolve(); _controlViewEntityElement = this; } public void OpenControl(ControlOpenModel model) { if (model.CloseElement != null) { CloseElementEvent += model.CloseElement; } if (panelContainer.Controls.Count == 0) { try { Configurate(GetConfig()); } catch (Exception ex) { DialogHelper.MessageException(ex.Message, $"{Title}. Ошибка при конфигурации"); } } if (model.ElementId.HasValue) { Element = _businessLogic.GetElement(new G { Id = model.ElementId }); if (Element == null) { DialogHelper.MessageException(_businessLogic.Errors, $"{Title}. Ошибки при получении элемента"); } } 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, $"{Title}. Ошибка при сбросе значений"); } } }; toolStripButtonClose.Click += (object sender, EventArgs e) => { if (_haveChages && DialogHelper.MessageQuestion("Имеется несохраненные данные, вы действительно хотите закрыть элемент?", "Закрытие элемента") == DialogResult.Yes) { if (!Save()) { return; } } CloseElementEvent?.Invoke(ControlId); Dispose(); }; } private void Configurate(ControlViewEntityElementConfiguration config) { // Загрузка подпунктов в контекстное меню и в пункт меню "Действие" 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; contextMenuStripElement.Items.Add(itemContext); } } // либо скрытие пункта, если не предусмотренно подпунктов else { toolStripSplitButtonActions.Visible = false; toolStripSeparator1.Visible = false; } var attributeClass = typeof(E).GetCustomAttribute(); 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(); 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() && Type.GetType(attribute.ControlTypeObject) != null) { 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(); 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(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, "Ошибки при сохранении элемента"); return false; } _haveChages = false; DialogHelper.MessageInformation("Сохранение прошло успешно", "Сообщение"); return true; } return false; } private ControlViewEntityElementConfiguration GetConfig() => _genericControlViewEntityElement?.GetConfigControl(); protected bool FillModel(S model) { if (CheckValues.GetInvocationList().Select(x => (bool)x.DynamicInvoke()).ToList().Any(x => !x)) { return false; } try { GetValues(model); return true; } catch (Exception ex) { DialogHelper.MessageException(ex.Message, "Ошибка при получении значений"); } return false; } } }