diff --git a/插件库/Lskj.Control/AuditPanel2.Designer.cs b/插件库/Lskj.Control/AuditPanel2.Designer.cs index 866cd8d..89c4397 100644 --- a/插件库/Lskj.Control/AuditPanel2.Designer.cs +++ b/插件库/Lskj.Control/AuditPanel2.Designer.cs @@ -28,9 +28,10 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); this.dpb_Tools = new DevExpress.XtraEditors.DropDownButton(); - this.pMenu = new DevExpress.XtraBars.PopupMenu(); - this.barManager1 = new DevExpress.XtraBars.BarManager(); + this.pMenu = new DevExpress.XtraBars.PopupMenu(this.components); + this.barManager1 = new DevExpress.XtraBars.BarManager(this.components); this.barDockControlTop = new DevExpress.XtraBars.BarDockControl(); this.barDockControlBottom = new DevExpress.XtraBars.BarDockControl(); this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl(); @@ -40,11 +41,17 @@ this.btnSave = new DevExpress.XtraEditors.SimpleButton(); this.btnAccradit = new DevExpress.XtraEditors.SimpleButton(); this.btnPrint = new DevExpress.XtraEditors.DropDownButton(); - this.pMprint = new DevExpress.XtraBars.PopupMenu(); + this.pMprint = new DevExpress.XtraBars.PopupMenu(this.components); this.btnAttach = new DevExpress.XtraEditors.SimpleButton(); this.btnSpare = new DevExpress.XtraEditors.SimpleButton(); this.pcTool = new DevExpress.XtraEditors.PanelControl(); this.dbpFP = new DevExpress.XtraEditors.DropDownButton(); + this.pmFP = new DevExpress.XtraBars.PopupMenu(this.components); + this.barManager2 = new DevExpress.XtraBars.BarManager(this.components); + this.barDockControl1 = new DevExpress.XtraBars.BarDockControl(); + this.barDockControl2 = new DevExpress.XtraBars.BarDockControl(); + this.barDockControl3 = new DevExpress.XtraBars.BarDockControl(); + this.barDockControl5 = new DevExpress.XtraBars.BarDockControl(); this.simpleButton2 = new DevExpress.XtraEditors.SimpleButton(); this.btnAdditional = new DevExpress.XtraEditors.SimpleButton(); this.btnRecord = new DevExpress.XtraEditors.SimpleButton(); @@ -65,20 +72,16 @@ this.simpleButton1 = new DevExpress.XtraEditors.SimpleButton(); this.btnBackTop = new DevExpress.XtraEditors.SimpleButton(); this.pcBillDetail = new DevExpress.XtraEditors.PanelControl(); - this.gcDetail = new Lskj.Control.GridControlEx(); this.pcBillMain = new DevExpress.XtraEditors.XtraScrollableControl(); this.txt_billDocumentId = new Lskj.Control.LabelTextEdit(); - this.pmFP = new DevExpress.XtraBars.PopupMenu(); - this.barManager2 = new DevExpress.XtraBars.BarManager(); - this.barDockControl1 = new DevExpress.XtraBars.BarDockControl(); - this.barDockControl2 = new DevExpress.XtraBars.BarDockControl(); - this.barDockControl3 = new DevExpress.XtraBars.BarDockControl(); - this.barDockControl5 = new DevExpress.XtraBars.BarDockControl(); + this.gcDetail = new Lskj.Control.GridControlEx(); ((System.ComponentModel.ISupportInitialize)(this.pMenu)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.barManager1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pMprint)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pcTool)).BeginInit(); this.pcTool.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pmFP)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.barManager2)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.panelControl1)).BeginInit(); this.panelControl1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitMain)).BeginInit(); @@ -95,8 +98,6 @@ ((System.ComponentModel.ISupportInitialize)(this.pcBillDetail)).BeginInit(); this.pcBillDetail.SuspendLayout(); this.pcBillMain.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pmFP)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.barManager2)).BeginInit(); this.SuspendLayout(); // // dpb_Tools @@ -288,6 +289,48 @@ this.dbpFP.TabIndex = 37; this.dbpFP.Text = "分配"; // + // pmFP + // + this.pmFP.Manager = this.barManager2; + this.pmFP.Name = "pmFP"; + // + // barManager2 + // + this.barManager2.DockControls.Add(this.barDockControl1); + this.barManager2.DockControls.Add(this.barDockControl2); + this.barManager2.DockControls.Add(this.barDockControl3); + this.barManager2.DockControls.Add(this.barDockControl5); + this.barManager2.Form = this; + this.barManager2.MaxItemId = 0; + // + // barDockControl1 + // + this.barDockControl1.CausesValidation = false; + this.barDockControl1.Dock = System.Windows.Forms.DockStyle.Top; + this.barDockControl1.Location = new System.Drawing.Point(0, 0); + this.barDockControl1.Size = new System.Drawing.Size(1152, 0); + // + // barDockControl2 + // + this.barDockControl2.CausesValidation = false; + this.barDockControl2.Dock = System.Windows.Forms.DockStyle.Bottom; + this.barDockControl2.Location = new System.Drawing.Point(0, 780); + this.barDockControl2.Size = new System.Drawing.Size(1152, 0); + // + // barDockControl3 + // + this.barDockControl3.CausesValidation = false; + this.barDockControl3.Dock = System.Windows.Forms.DockStyle.Left; + this.barDockControl3.Location = new System.Drawing.Point(0, 0); + this.barDockControl3.Size = new System.Drawing.Size(0, 780); + // + // barDockControl5 + // + this.barDockControl5.CausesValidation = false; + this.barDockControl5.Dock = System.Windows.Forms.DockStyle.Right; + this.barDockControl5.Location = new System.Drawing.Point(1152, 0); + this.barDockControl5.Size = new System.Drawing.Size(0, 780); + // // simpleButton2 // this.simpleButton2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -536,18 +579,6 @@ this.pcBillDetail.Size = new System.Drawing.Size(1148, 358); this.pcBillDetail.TabIndex = 0; // - // gcDetail - // - this.gcDetail.AdapterObj = null; - this.gcDetail.Dock = System.Windows.Forms.DockStyle.Fill; - this.gcDetail.Location = new System.Drawing.Point(2, 120); - this.gcDetail.Margin = new System.Windows.Forms.Padding(8, 10, 8, 10); - this.gcDetail.Name = "gcDetail"; - this.gcDetail.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum; - this.gcDetail.Size = new System.Drawing.Size(1144, 236); - this.gcDetail.SysModel = null; - this.gcDetail.TabIndex = 12; - // // pcBillMain // this.pcBillMain.Controls.Add(this.txt_billDocumentId); @@ -574,61 +605,31 @@ this.txt_billDocumentId.TabIndex = 0; this.txt_billDocumentId.Visible = false; // - // pmFP + // gcDetail // - this.pmFP.Manager = this.barManager2; - this.pmFP.Name = "pmFP"; - // - // barManager2 - // - this.barManager2.DockControls.Add(this.barDockControl1); - this.barManager2.DockControls.Add(this.barDockControl2); - this.barManager2.DockControls.Add(this.barDockControl3); - this.barManager2.DockControls.Add(this.barDockControl5); - this.barManager2.Form = this; - this.barManager2.MaxItemId = 0; - // - // barDockControl1 - // - this.barDockControl1.CausesValidation = false; - this.barDockControl1.Dock = System.Windows.Forms.DockStyle.Top; - this.barDockControl1.Location = new System.Drawing.Point(0, 0); - this.barDockControl1.Size = new System.Drawing.Size(1152, 0); - // - // barDockControl2 - // - this.barDockControl2.CausesValidation = false; - this.barDockControl2.Dock = System.Windows.Forms.DockStyle.Bottom; - this.barDockControl2.Location = new System.Drawing.Point(0, 743); - this.barDockControl2.Size = new System.Drawing.Size(1152, 0); - // - // barDockControl3 - // - this.barDockControl3.CausesValidation = false; - this.barDockControl3.Dock = System.Windows.Forms.DockStyle.Left; - this.barDockControl3.Location = new System.Drawing.Point(0, 0); - this.barDockControl3.Size = new System.Drawing.Size(0, 743); - // - // barDockControl5 - // - this.barDockControl5.CausesValidation = false; - this.barDockControl5.Dock = System.Windows.Forms.DockStyle.Right; - this.barDockControl5.Location = new System.Drawing.Point(1152, 0); - this.barDockControl5.Size = new System.Drawing.Size(0, 743); + this.gcDetail.AdapterObj = null; + this.gcDetail.Dock = System.Windows.Forms.DockStyle.Fill; + this.gcDetail.Location = new System.Drawing.Point(2, 120); + this.gcDetail.Margin = new System.Windows.Forms.Padding(8, 10, 8, 10); + this.gcDetail.Name = "gcDetail"; + this.gcDetail.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum; + this.gcDetail.Size = new System.Drawing.Size(1144, 236); + this.gcDetail.SysModel = null; + this.gcDetail.TabIndex = 12; // // AuditPanel2 // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - this.Controls.Add(this.barDockControl3); - this.Controls.Add(this.barDockControl5); - this.Controls.Add(this.barDockControl2); - this.Controls.Add(this.barDockControl1); this.Controls.Add(this.panelControl1); this.Controls.Add(this.pcTool); this.Controls.Add(this.barDockControlLeft); this.Controls.Add(this.barDockControlRight); this.Controls.Add(this.barDockControlBottom); this.Controls.Add(this.barDockControlTop); + this.Controls.Add(this.barDockControl3); + this.Controls.Add(this.barDockControl5); + this.Controls.Add(this.barDockControl2); + this.Controls.Add(this.barDockControl1); this.Name = "AuditPanel2"; this.Size = new System.Drawing.Size(1152, 780); ((System.ComponentModel.ISupportInitialize)(this.pMenu)).EndInit(); @@ -636,6 +637,8 @@ ((System.ComponentModel.ISupportInitialize)(this.pMprint)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pcTool)).EndInit(); this.pcTool.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pmFP)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.barManager2)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.panelControl1)).EndInit(); this.panelControl1.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitMain)).EndInit(); @@ -652,8 +655,6 @@ ((System.ComponentModel.ISupportInitialize)(this.pcBillDetail)).EndInit(); this.pcBillDetail.ResumeLayout(false); this.pcBillMain.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.pmFP)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.barManager2)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -683,11 +684,11 @@ public DevExpress.XtraEditors.SimpleButton btnAdditional; private DevExpress.XtraEditors.SplitContainerControl splitMain; private DevExpress.XtraEditors.PanelControl pcBillDetail; - public GridControlEx gcDetail; private DevExpress.XtraEditors.XtraScrollableControl pcBillMain; private LabelTextEdit txt_billDocumentId; private DevExpress.XtraTab.XtraTabControl tabMain; private DevExpress.XtraTab.XtraTabPage tabpage_finish; private GridControlEx gridFinish; private DevExpress.XtraEditors.PanelControl pl_top; - private DevExpress.XtraEditors.PanelControl pl_top_s \ No newline at end of file + private DevExpress.XtraEditors.PanelControl pl_top_searchCond; + private LabelCheckDa \ No newline at end of file diff --git a/插件库/Lskj.Control/AuditPanel2.cs b/插件库/Lskj.Control/AuditPanel2.cs index 279d1e2..0d7c7db 100644 --- a/插件库/Lskj.Control/AuditPanel2.cs +++ b/插件库/Lskj.Control/AuditPanel2.cs @@ -1461,6 +1461,7 @@ namespace Lskj.Control { this.ControlObj.CanExecControl = false; this.ControlObj.SetAllControlValue(this._drBillInfoMsg); + this.SetColor(); this.ControlObj.CanExecControl = true; // 必填字段 @@ -2279,6 +2280,9 @@ namespace Lskj.Control case 1: if (showMsg) MessageUtil.Show(ResourceKeys.SaveSuccess); + + AuditChangeLog.SaveHeaderChangeLog(this._drBillInfoMsg, this.ControlObj, this.SysModel.BillDocumentId, this.SysModel.StepCode, ERPInfo.Instance.UserId); + save = true; break; case 9: @@ -3558,4 +3562,14 @@ namespace Lskj.Control { this.SetUnionValue(UnionModel, rowItem[gridModel.FieldName] + "", rowItem); } - //this.gridView.SetRowCellValue(this.g \ No newline at end of file + //this.gridView.SetRowCellValue(this.gridView.FocusedRowHandle, this.gridView.Columns[gridModel.FieldName], result); + } + } + catch (Exception) + { + + } + } + } + catch (Exception ex) + \ No newline at end of file diff --git a/插件库/Lskj.Control/BandedGridControlEx.cs b/插件库/Lskj.Control/BandedGridControlEx.cs index 20da0fd..3cb9551 100644 --- a/插件库/Lskj.Control/BandedGridControlEx.cs +++ b/插件库/Lskj.Control/BandedGridControlEx.cs @@ -1310,7 +1310,11 @@ namespace Lskj.Control if (this is BandedGridControlEx) { + frozenColumnGridBands.Clear(); + frozenGridBands.Clear(); GridBand gridBandEmpty = new GridBand(); + List autoFixColumns = new List(); + bool hasVisibleBandEmptyRow = false; foreach (GridColumn item in bandedGridView.Columns) { if (item.FieldName.Contains("|")) @@ -1322,6 +1326,20 @@ namespace Lskj.Control else { bandEmptyRows.Add(item.FieldName); + bool emptyColumnVisible = true; + if (item.FieldName.Contains("_")) + { + string[] colparame = item.FieldName.Split('_'); + int width = 0; + if (colparame.Length >= 2 && Int32.TryParse(colparame[1], out width)) + { + emptyColumnVisible = width > 0; + } + } + if (emptyColumnVisible) + { + hasVisibleBandEmptyRow = true; + } } } foreach (string bandName in bandFields) @@ -1343,6 +1361,7 @@ namespace Lskj.Control gridBandEmpty.AppearanceHeader.Font = new Font("宋体", 9, FontStyle.Bold); gridBandEmpty.AppearanceHeader.Options.UseTextOptions = true; gridBandEmpty.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; + gridBandEmpty.Visible = hasVisibleBandEmptyRow; bandedGridView.Bands.Insert(0, gridBandEmpty); } bandedGridView.BeginDataUpdate(); @@ -1351,6 +1370,7 @@ namespace Lskj.Control { BandedGridColumn col = bandedGridView.Columns[i]; int vsNum = 0; bool isNum = false; string FieldName = col.FieldName; string bandTitle = string.Empty; + bool isFixColumn = false;//是否有冻结列 col.VisibleIndex = i; if (col.FieldName.Contains("|")) { @@ -1414,6 +1434,12 @@ namespace Lskj.Control col.DisplayFormat.FormatString = dataFormat; } } + if (colparame.Length > 4) + { + //冻结列 + isFixColumn = "1".Equals(colparame[4]); + + } } } } @@ -1437,6 +1463,11 @@ namespace Lskj.Control } bandedGridView.Columns.Add(col); } + if (isFixColumn && col.OwnerBand != null) + { + autoFixColumns.Add(col); + } + if (isNum) col.Width = vsNum; col.OptionsColumn.AllowEdit = isEdit; @@ -1448,6 +1479,29 @@ namespace Lskj.Control col.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center; bandedGridView.OptionsView.ShowFooter = isShowFooter; } + + + foreach (IGrouping group in autoFixColumns.GroupBy(x => x.OwnerBand).ToList()) + { + GridBand gridBand = group.Key; + List fixColumns = group.ToList(); + List visibleColumns = gridBand.Columns.Cast().Where(x => x.Visible && x.Width > 0).ToList(); + if (visibleColumns.Count > 0 && visibleColumns.All(x => fixColumns.Contains(x))) + { + if (!frozenGridBands.Contains(gridBand)) frozenGridBands.Add(gridBand); + gridBand.Fixed = FixedStyle.Left; + } + else + { + foreach (BandedGridColumn fixColumn in fixColumns) + { + if (fixColumn.OwnerBand != null) + { + FixLeftItemClick(fixColumn, EventArgs.Empty); + } + } + } + } bandedGridView.EndDataUpdate(); //this.bandedGridView.DataSource = bandedGridView.DataSource as DataTable; } @@ -1862,6 +1916,14 @@ namespace Lskj.Control { try { + ////没有设置右键时,ContextMenuStrip为空。右键菜单可能会必须选中才能关闭,设置空ContextMenuStrip可用解决 + if (this.gridControl.ContextMenuStrip == null) + { + ContextMenuStrip MenuStrip = new ContextMenuStrip(); + this.gridControl.ContextMenuStrip = MenuStrip; + } + + if (e.MenuType == GridMenuType.Column) { GridViewColumnMenu columnMenu = e.Menu as GridViewColumnMenu; diff --git a/插件库/Lskj.Control/BaseUserControl.cs b/插件库/Lskj.Control/BaseUserControl.cs index c814863..30fee9d 100644 --- a/插件库/Lskj.Control/BaseUserControl.cs +++ b/插件库/Lskj.Control/BaseUserControl.cs @@ -46,7 +46,8 @@ namespace Lskj.Control /// Label 默认颜色 /// protected Color DefaultLabelForceColor = Color.Black; - + + /// /// Gets or sets the is empty. @@ -114,6 +115,10 @@ namespace Lskj.Control /// 控件Model /// public virtual ControlModel Model { get; set; } + /// + /// 控件背景颜色 + /// + public virtual Color BackgroundColor { get; set; } protected int GetCharWidth() diff --git a/插件库/Lskj.Control/FrmColorDescription.Designer.cs b/插件库/Lskj.Control/FrmColorDescription.Designer.cs new file mode 100644 index 0000000..ad63c4e --- /dev/null +++ b/插件库/Lskj.Control/FrmColorDescription.Designer.cs @@ -0,0 +1,41 @@ + +namespace Lskj.Control +{ + partial class FrmColorDescription + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.gridcolor = new Lskj.Control.GridControlEx(); + this.SuspendLayout(); + // + // gridcolor + // + this.gridcolor.AdapterObj = null; + this.gridcolor.Dock = System.Windows.Forms.DockStyle.Fill; + this.gridcolor.Location = new System.Drawing.Point(0, 0); + this.gridcolor.Margin = new System.Windows.Forms.Padding(4); + \ No newline at end of file diff --git a/插件库/Lskj.Control/FrmColorDescription.cs b/插件库/Lskj.Control/FrmColorDescription.cs new file mode 100644 index 0000000..a60e2eb --- /dev/null +++ b/插件库/Lskj.Control/FrmColorDescription.cs @@ -0,0 +1,91 @@ +using DevExpress.XtraEditors.Repository; +using DevExpress.XtraGrid.Columns; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Lskj.Control +{ + public partial class FrmColorDescription : BaseForm + { + + public DataTable colorTable = null; + + public FrmColorDescription() + { + InitializeComponent(); + } + + public FrmColorDescription(DataTable dataTable) + { + InitializeComponent(); + colorTable = dataTable; + this.creatDetailControl(); + } + + //创建颜色条件表格列 + private void creatDetailControl() + { + + + + GridColumn conditionColumn = new GridColumn(); + conditionColumn.Caption = "条件"; + conditionColumn.FieldName = "condition"; + conditionColumn.Visible = true; + conditionColumn.VisibleIndex = 1; + + + + RepositoryItemColorPickEdit repositoryItemForcecolorPickEdit = new RepositoryItemColorPickEdit(); + //repositoryItemForcecolorPickEdit.EditValueChanging += new DevExpress.XtraEditors.Controls.ChangingEventHandler(OnColorPickEdit); + RepositoryItemColorPickEdit repositoryItemBackcolorPickEdit = new RepositoryItemColorPickEdit(); + //repositoryItemBackcolorPickEdit.EditValueChanging += new DevExpress.XtraEditors.Controls.ChangingEventHandler(OnBackEditValueChanging); + + GridColumn forcecolorColumn = new GridColumn(); + forcecolorColumn.Caption = "前景色"; + forcecolorColumn.FieldName = "forcecolor"; + forcecolorColumn.Visible = true; + forcecolorColumn.VisibleIndex = 2; + forcecolorColumn.ColumnEdit = repositoryItemForcecolorPickEdit; + + GridColumn backcolorColumn = new GridColumn(); + backcolorColumn.Caption = "背景色"; + backcolorColumn.FieldName = "backcolor"; + backcolorColumn.Visible = true; + backcolorColumn.VisibleIndex = 3; + backcolorColumn.ColumnEdit = repositoryItemBackcolorPickEdit; + + + //RepositoryItemCheckEdit checkEdit = new RepositoryItemCheckEdit(); + //checkEdit.ValueChecked = 1; + //checkEdit.ValueUnchecked = 0; + //checkEdit.ValueGrayed = 3; + + //GridColumn ifBoldColumn = new GridColumn(); + //ifBoldColumn.Caption = "加粗"; + //ifBoldColumn.FieldName = "ifBold"; + //ifBoldColumn.ColumnEdit = checkEdit; + //ifBoldColumn.Visible = true; + //ifBoldColumn.VisibleIndex = 8; + + //GridColumn ifItalicColumn = new GridColumn(); + //ifItalicColumn.Caption = "倾斜"; + //ifItalicColumn.FieldName = "ifItalic"; + //ifItalicColumn.ColumnEdit = checkEdit; + //ifItalicColumn.Visible = true; + //ifItalicColumn.VisibleIndex = 9; + + //GridColumn ifStrickOutColumn = new GridColumn(); + //ifStrickOutColumn.Caption = "删除线"; + //ifStrickOutColumn.FieldName = "ifStrickOut"; + //ifStrickOutColumn.ColumnEdit = checkEdit; + //ifStrickOutColumn.Visible = true; + //ifStrickOutColumn.VisibleIndex = 10; + + //GridColumn ii \ No newline at end of file diff --git a/插件库/Lskj.Control/FrmColorDescription.resx b/插件库/Lskj.Control/FrmColorDescription.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/插件库/Lskj.Control/FrmColorDescription.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/插件库/Lskj.Control/FrmSettingTableName.Designer.cs b/插件库/Lskj.Control/FrmSettingTableName.Designer.cs new file mode 100644 index 0000000..2aa4981 --- /dev/null +++ b/插件库/Lskj.Control/FrmSettingTableName.Designer.cs @@ -0,0 +1,91 @@ + +namespace Lskj.Control +{ + partial class FrmSettingTableName + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.labelAutoTextEdit1 = new Lskj.Control.LabelAutoTextEdit(); + this.btnOk = new DevExpress.XtraEditors.SimpleButton(); + this.btnCancel = new DevExpress.XtraEditors.SimpleButton(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // labelAutoTextEdit1 + // + this.labelAutoTextEdit1.BackColor = System.Drawing.Color.Transparent; + this.labelAutoTextEdit1.BackgroundColor = System.Drawing.Color.Empty; + this.labelAutoTextEdit1.EditText = ""; + this.labelAutoTextEdit1.FontSize = 0F; + this.labelAutoTextEdit1.FormKey = ""; + this.labelAutoTextEdit1.LabelText = ""; + this.labelAutoTextEdit1.Location = new System.Drawing.Point(8, 33); + this.labelAutoTextEdit1.Model = null; + this.labelAutoTextEdit1.Name = "labelAutoTextEdit1"; + this.labelAutoTextEdit1.NullText = ""; + this.labelAutoTextEdit1.ReadOnly = false; + this.labelAutoTextEdit1.Required = false; + this.labelAutoTextEdit1.Size = new System.Drawing.Size(268, 21); + this.labelAutoTextEdit1.TabIndex = 0; + this.labelAutoTextEdit1.TextField = ""; + this.labelAutoTextEdit1.ValueField = ""; + this.labelAutoTextEdit1.ValueMember = ""; + // + // btnOk + // + this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOk.Appearance.Font = new System.Drawing.Font("宋体", 9F); + this.btnOk.Appearance.Options.UseFont = true; + this.btnOk.Location = new System.Drawing.Point(152, 58); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size(59, 28); + this.btnOk.TabIndex = 18; + this.btnOk.Text = "确定"; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.Appearance.Font = new System.Drawing.Font("宋体", 9F); + this.btnCancel.Appearance.Options.UseFont = true; + this.btnCancel.Location = new System.Drawing.Point(217, 58); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(59, 28); + this.btnCancel.TabIndex = 19; + this.btnCancel.Text = "取消"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(269, 12); + this.label1.TabIndex = 20; + this.label1.Text = "文件名称重复,以工作表的形式添加,请输入名称"; + // + // FrmSettingTableName + // + this.Appearan \ No newline at end of file diff --git a/插件库/Lskj.Control/FrmSettingTableName.cs b/插件库/Lskj.Control/FrmSettingTableName.cs new file mode 100644 index 0000000..a9c804e --- /dev/null +++ b/插件库/Lskj.Control/FrmSettingTableName.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Lskj.Control +{ + public partial class FrmSettingTableName : BaseForm + { + public string TabName; + + public FrmSettingTableName() + { + InitializeComponent(); + InitEvent(); + } + + public FrmSettingTableName(string name) + { + InitializeComponent(); + InitEvent(); + this.labelAutoTextEdit1.EditText = TabName = name; + } + + /// + /// 初始化窗 \ No newline at end of file diff --git a/插件库/Lskj.Control/FrmSettingTableName.resx b/插件库/Lskj.Control/FrmSettingTableName.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/插件库/Lskj.Control/FrmSettingTableName.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/插件库/Lskj.Control/GridControlEx.cs b/插件库/Lskj.Control/GridControlEx.cs index 9da89a7..a207ba2 100644 --- a/插件库/Lskj.Control/GridControlEx.cs +++ b/插件库/Lskj.Control/GridControlEx.cs @@ -509,7 +509,7 @@ namespace Lskj.Control MainGvTool.AutoPopDelay = 1000000;//提示框显示时间 10分钟 MainGvTool.BeforeShow += new ToolTipControllerBeforeShowEventHandler(MainGvTool_BeforeShow); this.gridControl.ToolTipController = MainGvTool; - this.gridView.PopupMenuShowing += new PopupMenuShowingEventHandler(OnGridView_PopupMenuShowing);//添加Footer菜单选项 + //this.gridView.PopupMenuShowing += new PopupMenuShowingEventHandler(OnGridView_PopupMenuShowing);//添加Footer菜单选项 this.gridView.Click += new EventHandler(OnGridView_Click);//点击复制Footer数据信息 if (SystemInfo.Instance.SelectColorHighlight) { @@ -2610,6 +2610,7 @@ namespace Lskj.Control if (this.ColumnList == null || this.ColumnList.Count == 0) { bool isShowFooter = false; + List autoFixColumns = new List(); for (int i = 0; i < gridView.Columns.Count; i++) { try @@ -2676,6 +2677,14 @@ namespace Lskj.Control col.DisplayFormat.FormatString = dataFormat; } } + if (colSplit.Length > 4) + { + // 是否冻结列:1冻结 + if ("1".Equals(colSplit[4])) + { + autoFixColumns.Add(col); + } + } } } } @@ -2690,6 +2699,10 @@ namespace Lskj.Control } } + foreach (GridColumn col in autoFixColumns.Where(x => x.Visible && x.Width > 0)) + { + col.Fixed = FixedStyle.Left; + } } } @@ -5157,8 +5170,7 @@ namespace Lskj.Control btnEdit.SeparatorChar = ','; btnEdit.ValueMember = model.FieldType == ControlType.LabSelectReturnIdNew ? model.ValueMember : model.TextMember; - //model.ModuleFrameDisplayText 2026-5-23 丁哥说不需要这个字段 - if (model.FieldType == ControlType.LabSelectReturnIdNew) + if (model.ModuleFrameDisplayText && model.FieldType == ControlType.LabSelectReturnIdNew) { DataTable dataTable = MainImpl.GetDataTableResult(modelLookUp.SysModel.MenuSql); btnEdit.DataSource = dataTable; @@ -5467,7 +5479,6 @@ namespace Lskj.Control this.gridView.RowStyle -= new RowStyleEventHandler(OnGridViewRowStyle); this.gridView.RowStyle += new RowStyleEventHandler(OnGridViewRowStyle); } - } } } @@ -5514,15 +5525,24 @@ namespace Lskj.Control int rowCount = this.gridView.RowCount; if (rowCount == 0) return; - // 计算数字部分宽度 - int numberWidth = (int)(rowCount.ToString().Length * 7.5) + 16; + // 获取网格实际使用的行字体 + Font rowFont = this.gridView.Appearance.Row.Font + ?? this.gridView.GridControl?.Font + ?? SystemFonts.DefaultFont; - // 设置最终宽度(取较大值,并在40-80px之间) - this.gridView.IndicatorWidth = Math.Max(40, Math.Min(80, numberWidth)); + // 用最大行号实测文本宽度(而非估算) + string maxNumber = rowCount.ToString(); + int textWidth = TextRenderer.MeasureText(maxNumber, rowFont).Width; + + // 附加宽度:行指示器图标(~12px) + 左右间距(~10px) + 边框 + int indicatorWidth = textWidth + 14; + + // 限制范围 40-80px + this.gridView.IndicatorWidth = Math.Max(40, Math.Min(80, indicatorWidth)); } catch (Exception ex) { - + // 这里可以加日志 } } @@ -6470,6 +6490,8 @@ namespace Lskj.Control string cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + ""); try { + + if (!string.IsNullOrWhiteSpace(cond) && ReplaceHelper.EvalCond(cond)) { GridRowColorModel model = new GridRowColorModel(item); @@ -7054,6 +7076,14 @@ namespace Lskj.Control { try { + //没有设置右键时,ContextMenuStrip为空。右键菜单可能会必须选中才能关闭,设置空ContextMenuStrip可用解决 + if (this.gridControl.ContextMenuStrip == null) + { + ContextMenuStrip MenuStrip = new ContextMenuStrip(); + this.gridControl.ContextMenuStrip = MenuStrip; + } + + if (e.MenuType == GridMenuType.Column) { GridViewColumnMenu columnMenu = e.Menu as GridViewColumnMenu; @@ -7087,6 +7117,24 @@ namespace Lskj.Control if (ExportPermission) columnMenu.Items.Add(itemExportColumn); columnMenu.Items.AddRange(new DXMenuItem[] { itemPrintColumn, itemMultifunction, itemSortColumn, itemColumnSift, itemChartColumn, itemBsChartColumn, itemBsChartShowClick }); } + else if (e.MenuType == GridMenuType.Summary) + { + GridHitInfo info; + Point pt = this.gridView.GridControl.PointToClient(System.Windows.Forms.Control.MousePosition); + info = this.gridView.CalcHitInfo(pt); + if (e.Menu is DevExpress.XtraGrid.Menu.GridViewFooterMenu)//如果是Footer菜单则增加复制行选项 + { + DXMenuCheckItem menuItemCell = new DXMenuCheckItem(); + menuItemCell.Tag = info; + menuItemCell.Caption = "复制合计"; + menuItemCell.Click += new EventHandler(OnMenuItem_Click); + DXMenuCheckItem menuItemRow = new DXMenuCheckItem(); + menuItemRow.Caption = "复制合计行"; + menuItemRow.Tag = info; + menuItemRow.Click += new EventHandler(OnMenuItem_Click); + e.Menu.Items.AddRange(new DXMenuCheckItem[] { menuItemCell, menuItemRow }); + } + } } catch (Exception ex) { diff --git a/插件库/Lskj.Control/LabApiButtonEdit.cs b/插件库/Lskj.Control/LabApiButtonEdit.cs index 60f6617..a32254c 100644 --- a/插件库/Lskj.Control/LabApiButtonEdit.cs +++ b/插件库/Lskj.Control/LabApiButtonEdit.cs @@ -173,10 +173,22 @@ namespace Lskj.Control } } } + + + /// /// 说明:格式化文本控件 /// 创建人:王一帆 /// 创建日期:2019-10-17 /// 修改人: /// 修改日期: - /// \ No newline at end of file + /// 修改备注: + /// 版本:1.0 + /// + /// The format string. + public void TextFormat(string formatString) + { + if (!string.IsNullOrWhiteSpace(formatString)) + { + this.txtEdit.Properties.Mask.EditMask = "##########" + (formatString == "#" ? "0" : formatString);//#代表位数 + \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelAutoGridLook.cs b/插件库/Lskj.Control/LabelAutoGridLook.cs index 6cdc5c9..f0f6ba2 100644 --- a/插件库/Lskj.Control/LabelAutoGridLook.cs +++ b/插件库/Lskj.Control/LabelAutoGridLook.cs @@ -809,4 +809,18 @@ namespace Lskj.Control { this.EditValue = rowItem[ValueMember] + ""; } - \ No newline at end of file + } + catch (Exception ex) + { + string Message = ErrorMessage.PromptErrorMessage(ex); + MessageUtil.Show(Message, ex.Message); + } + } + } + + + + /// + /// 说明:释放时清理数据源 + /// 创建人:龚宇超 + /// 创建日期:2018-03-16

+ /// 说明:添加操作后 + /// 创建人:龚宇超 + /// 创建日期:2018-04-03 + /// 修改人: + /// 修改日期: + /// 修改备注: + /// 版本:1.0 + ///
+ \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelBillSourceComboxEdit.cs b/插件库/Lskj.Control/LabelBillSourceComboxEdit.cs index 4fd16b9..05e73f4 100644 --- a/插件库/Lskj.Control/LabelBillSourceComboxEdit.cs +++ b/插件库/Lskj.Control/LabelBillSourceComboxEdit.cs @@ -350,4 +350,8 @@ namespace Lskj.Control string AddModuleSpec = "SpeciesNo"; if (!string.IsNullOrEmpty(this.Model.AddModuleSpec)) AddModuleSpec = this.Model.AddModuleSpec; - // 固定传入参数(窗口标题、操作员ID \ No newline at end of file + // 固定传入参数(窗口标题、操作员ID、操作员名称、权限、模版编号) + string[] defaultArgs = string.Format(ModuleArgs.DefaultArgs, this.LabelText + "-添加", ERPInfo.Instance.UserId, ERPInfo.Instance.UserName, "0", this.Model.AddModuleId).Split('~'); + + string[] menuArgs = { string.Format(ModuleArgs.PubAddArgs, ""), "0", "", AddModuleSpec, "默认分类", "", "", "", "", "" }; + string[] args = defaultArgs \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelBrowserEdit.cs b/插件库/Lskj.Control/LabelBrowserEdit.cs index fcbaf1c..6a7fe14 100644 --- a/插件库/Lskj.Control/LabelBrowserEdit.cs +++ b/插件库/Lskj.Control/LabelBrowserEdit.cs @@ -189,24 +189,4 @@ namespace Lskj.Control /// The instance containing the event data. private void picBrowser_Click(object sender, EventArgs e) { - try - { - PictureBox pic = (PictureBox)sender; - string url = EditText; - if (string.IsNullOrEmpty(url)) - { - MessageUtil.Show(ResourceKeys.BrowserTip); - return; - } - Process.Start("iexplore.exe", url); - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - } -} + \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCalcEdit.cs b/插件库/Lskj.Control/LabelCalcEdit.cs index c12b2a4..77d88c8 100644 --- a/插件库/Lskj.Control/LabelCalcEdit.cs +++ b/插件库/Lskj.Control/LabelCalcEdit.cs @@ -152,29 +152,4 @@ namespace Lskj.Control { base.ReadOnly = value; this.txtEdit.Properties.ReadOnly = value; - this.lblText.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForceColor : base.DefaultLabelForceColor; - } - } - /// - /// 必填文本颜色 - /// - /// The color of the required label. - public override bool Required - { - get - { - return base.Required; - } - set - { - base.Required = value; - if (value) - { - this.lblText.ForeColor = base.RequiredLabelForceColor; - } - } - } - - - } -} + this.lblText.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelFor \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCheckAutoTextEdit.cs b/插件库/Lskj.Control/LabelCheckAutoTextEdit.cs index 843773b..0210118 100644 --- a/插件库/Lskj.Control/LabelCheckAutoTextEdit.cs +++ b/插件库/Lskj.Control/LabelCheckAutoTextEdit.cs @@ -167,23 +167,4 @@ namespace Lskj.Control /// 修改备注: /// 版本:1.0 ///
- /// The source of the event. - /// The instance containing the event data. - private void ckCheck_CheckedChanged(object sender, EventArgs e) - { - try - { - CheckEdit check = sender as CheckEdit; - TextEdit.Enabled = check.Checked; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - - } -} + /// The sou \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCheckComboxEdit.cs b/插件库/Lskj.Control/LabelCheckComboxEdit.cs index 9c4ed9a..f693f91 100644 --- a/插件库/Lskj.Control/LabelCheckComboxEdit.cs +++ b/插件库/Lskj.Control/LabelCheckComboxEdit.cs @@ -150,23 +150,4 @@ namespace Lskj.Control /// 修改备注: /// 版本:1.0 /// - /// The source of the event. - /// The instance containing the event data. - private void ckCheck_CheckedChanged(object sender, EventArgs e) - { - try - { - CheckEdit check = sender as CheckEdit; - TextEdit.Enabled = check.Checked; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - - } -} + /// The so \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCheckDateEdit.cs b/插件库/Lskj.Control/LabelCheckDateEdit.cs index c0d7d07..0d0586f 100644 --- a/插件库/Lskj.Control/LabelCheckDateEdit.cs +++ b/插件库/Lskj.Control/LabelCheckDateEdit.cs @@ -124,23 +124,4 @@ namespace Lskj.Control /// 修改备注: /// 版本:1.0 /// - /// The source of the event. - /// The instance containing the event data. - private void ckCheck_CheckedChanged(object sender, EventArgs e) - { - try - { - CheckEdit check = sender as CheckEdit; - TextEdit.Enabled = check.Checked; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - - } -} + /// The sou \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCheckEdit.cs b/插件库/Lskj.Control/LabelCheckEdit.cs index c535166..c9471e8 100644 --- a/插件库/Lskj.Control/LabelCheckEdit.cs +++ b/插件库/Lskj.Control/LabelCheckEdit.cs @@ -89,30 +89,4 @@ namespace Lskj.Control { base.ReadOnly = value; this.checkEdt.Properties.ReadOnly = value; - this.checkEdt.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForceColor : base.DefaultLabelForceColor; - } - } - /// - /// 必填文本颜色 - /// - /// The color of the required label. - public override bool Required - { - get - { - return base.Required; - } - set - { - base.Required = value; - if (value) - { - this.checkEdt.ForeColor = base.RequiredLabelForceColor; - } - } - } - - - - } -} + this.checkEdt.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForceColor : base.Defa \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCheckMultiAutoTextEdit.cs b/插件库/Lskj.Control/LabelCheckMultiAutoTextEdit.cs index de5782c..fe9970a 100644 --- a/插件库/Lskj.Control/LabelCheckMultiAutoTextEdit.cs +++ b/插件库/Lskj.Control/LabelCheckMultiAutoTextEdit.cs @@ -155,23 +155,4 @@ namespace Lskj.Control /// 修改备注: /// 版本:1.0 /// - /// The source of the event. - /// The instance containing the event data. - private void ckCheck_CheckedChanged(object sender, EventArgs e) - { - try - { - CheckEdit check = sender as CheckEdit; - MultiAutoEdit.Enabled = check.Checked; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - - } -} + /// The source \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelCheckText.cs b/插件库/Lskj.Control/LabelCheckText.cs index b42887f..f8fd18f 100644 --- a/插件库/Lskj.Control/LabelCheckText.cs +++ b/插件库/Lskj.Control/LabelCheckText.cs @@ -31,6 +31,12 @@ namespace Lskj.Control /// The automatic text edit. public LabelTextEdit LabelTextEdit { get { return labelTextEdit1; } } + /// + /// 复选框日期控件 + /// + public TextEdit TextEdit { get { return labelTextEdit1.TextEdit; } } + + public LabelCheckText() { InitializeComponent(); @@ -144,24 +150,4 @@ namespace Lskj.Control /// 修改日期: /// 修改备注: /// 版本:1.0 - /// - /// The source of the event. - /// The instance containing the event data. - private void ckCheck_CheckedChanged(object sender, EventArgs e) - { - try - { - CheckEdit check = sender as CheckEdit; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message, ex.Message); - } - - } - - - - } -} + \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelComboxEdit.cs b/插件库/Lskj.Control/LabelComboxEdit.cs index a35b5e9..d9bd0c2 100644 --- a/插件库/Lskj.Control/LabelComboxEdit.cs +++ b/插件库/Lskj.Control/LabelComboxEdit.cs @@ -257,4 +257,16 @@ namespace Lskj.Control /// 修改人: /// 修改日期: /// 修改备注: - /// 版本: \ No newline at end of file + /// 版本:1.0 + /// + /// 数据源 + public void SetDataSource(DataTable dataSource) + { + try + { + foreach (DataRow item in dataSource.Rows) + { + ComboBoxModel model = new ComboBoxModel + { + ValueMember = ValueField, + D \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelComboxMutilPopupEdit.cs b/插件库/Lskj.Control/LabelComboxMutilPopupEdit.cs index 68a8a1f..e7fe836 100644 --- a/插件库/Lskj.Control/LabelComboxMutilPopupEdit.cs +++ b/插件库/Lskj.Control/LabelComboxMutilPopupEdit.cs @@ -219,4 +219,18 @@ namespace Lskj.Control this.ShowPopup(); } catch (Exception ex) - \ No newline at end of file + { + string Message = ErrorMessage.PromptErrorMessage(ex); + MessageUtil.Show(Message,ex.Message); + } + } + + private void simpleButton1_Click(object sender, EventArgs e) + { + try + { + this.ShowPopup(); + } + catch (Exception ex) + { + string Message = ErrorMessage.PromptEr \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelComboxPopupEdit.cs b/插件库/Lskj.Control/LabelComboxPopupEdit.cs index ccfceca..57461cb 100644 --- a/插件库/Lskj.Control/LabelComboxPopupEdit.cs +++ b/插件库/Lskj.Control/LabelComboxPopupEdit.cs @@ -261,4 +261,20 @@ namespace Lskj.Control { try { - this.ShowPopup(); \ No newline at end of file + this.ShowPopup(); + } + catch (Exception ex) + { + string Message = ErrorMessage.PromptErrorMessage(ex); + MessageUtil.Show(Message,ex.Message); + } + + } + + private void simpleButton1_Click(object sender, EventArgs e) + { + try + { + this.ShowPopup(); + } + catch (Exception ex) diff --git a/插件库/Lskj.Control/LabelDateEdit.cs b/插件库/Lskj.Control/LabelDateEdit.cs index fd492da..db993e4 100644 --- a/插件库/Lskj.Control/LabelDateEdit.cs +++ b/插件库/Lskj.Control/LabelDateEdit.cs @@ -207,4 +207,9 @@ namespace Lskj.Control /// 版本:1.0 /// /// The format string. - publi \ No newline at end of file + public void DateFormat(string formatString) + { + if (!string.IsNullOrWhiteSpace(formatString)) + { + this.txtEdit.Properties.DisplayFormat.FormatString = this.txtEdit.Properties.EditFormat.FormatString = this.txtEdit.Properties.Mask.EditMask = formatString; + this.txtEdit.Properties.DisplayFormat.FormatType = this.txtEdit.Properties.EditFormat.FormatType = DevExpress.Utils.FormatT \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelDateHalfDayEdit.cs b/插件库/Lskj.Control/LabelDateHalfDayEdit.cs index 65a90fb..c8f03f2 100644 --- a/插件库/Lskj.Control/LabelDateHalfDayEdit.cs +++ b/插件库/Lskj.Control/LabelDateHalfDayEdit.cs @@ -176,24 +176,4 @@ namespace Lskj.Control { this.popupControl.Size = this.specialDatePopup.Size; this.specialDatePopup.OwnerEdit = this.txtEdit; - this.specialDatePopup.SetValue(this.txtEdit.EditValue + ""); - } - - private void SpecialDatePopup_ConfirmClick(object sender, System.EventArgs e) - { - this.txtEdit.EditValue = this.specialDatePopup.SelectedValue; - this.txtEdit.ClosePopup(); - } - - private void SpecialDatePopup_ClearClick(object sender, System.EventArgs e) - { - this.txtEdit.EditValue = string.Empty; - this.txtEdit.ClosePopup(); - } - - private void SpecialDatePopup_CancelClick(object sender, System.EventArgs e) - { - this.txtEdit.ClosePopup(); - } - } -} + this.specialDatePopup.SetValue(this \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelGridSelectEdit.cs b/插件库/Lskj.Control/LabelGridSelectEdit.cs index df17c58..0163c82 100644 --- a/插件库/Lskj.Control/LabelGridSelectEdit.cs +++ b/插件库/Lskj.Control/LabelGridSelectEdit.cs @@ -342,30 +342,4 @@ namespace Lskj.Control } catch (Exception ex) { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - private void simpleButton4_Click(object sender, EventArgs e) - { - try - { - this.EditText = this.editValue = ""; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - public Control.Model.MyControl ControlObj { get; set; } - - - - - } -} + string Message = ErrorMessage.PromptErr \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelIntExtendEdit.cs b/插件库/Lskj.Control/LabelIntExtendEdit.cs index 6a838ae..97a89cb 100644 --- a/插件库/Lskj.Control/LabelIntExtendEdit.cs +++ b/插件库/Lskj.Control/LabelIntExtendEdit.cs @@ -227,28 +227,4 @@ namespace Lskj.Control { this.txtEdit.Text = (ReturnValue(this.txtEdit.Text) + 10) + ""; } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - private void simpleButton6_Click(object sender, EventArgs e) - { - - try - { - this.txtEdit.Text = "0"; - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - } - - - } -} + catch (E \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelMemoEdit.cs b/插件库/Lskj.Control/LabelMemoEdit.cs index 34b47a4..335e44c 100644 --- a/插件库/Lskj.Control/LabelMemoEdit.cs +++ b/插件库/Lskj.Control/LabelMemoEdit.cs @@ -153,30 +153,4 @@ namespace Lskj.Control { base.ReadOnly = value; this.txtEdit.Properties.ReadOnly = value; - this.lblText.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForceColor : base.DefaultLabelForceColor; - } - } - /// - /// 必填文本颜色 - /// - /// The color of the required label. - public override bool Required - { - get - { - return base.Required; - } - set - { - base.Required = value; - if (value) - { - this.lblText.ForeColor = base.RequiredLabelForceColor; - } - } - } - - - - } -} + this.lblText.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForce \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelMemoSpaceEdit.cs b/插件库/Lskj.Control/LabelMemoSpaceEdit.cs index b9c0b14..f0b773d 100644 --- a/插件库/Lskj.Control/LabelMemoSpaceEdit.cs +++ b/插件库/Lskj.Control/LabelMemoSpaceEdit.cs @@ -185,24 +185,4 @@ namespace Lskj.Control /// 修改日期: /// 修改备注: /// 版本:1.0 - /// - /// The source of the event. - /// The instance containing the event data. - void OnTxtEditEditValueChanged(object sender, EventArgs e) - { - try - { - this.EditText = txtEdit.Text.Replace("\r\n", ","); - } - catch (Exception ex) - { - string Message = ErrorMessage.PromptErrorMessage(ex); - MessageUtil.Show(Message,ex.Message); - } - - } - - - - } -} \ No newline at end of file + /// /// 只读文本颜色 /// - /// \ No newline at end of file + /// The color of the read only label. + public override bool ReadOnly + { + get + { + return base.ReadOnly; + } + set + { + base.ReadOnly = value; + this.txtEdit.Properties.ReadOnly = value; + this.lblText.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForceCo \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelRichEdit.cs b/插件库/Lskj.Control/LabelRichEdit.cs index 08193cc..6666b20 100644 --- a/插件库/Lskj.Control/LabelRichEdit.cs +++ b/插件库/Lskj.Control/LabelRichEdit.cs @@ -117,40 +117,4 @@ namespace Lskj.Control /// /// 是否只读 /// - /// The color of the read only label. - public override bool ReadOnly - { - get - { - return !this.TextEdit.Enabled; - } - set - { - base.ReadOnly = value; - this.TextEdit.Enabled = !value; - this.lblText.ForeColor = value ? base.ReadOnlyLabelForceColor : Required ? base.RequiredLabelForceColor : base.DefaultLabelForceColor; - } - } - /// - /// 必填文本颜色 - /// - /// The color of the required label. - public override bool Required - { - get - { - return base.Required; - } - set - { - base.Required = value; - if (value) - { - this.lblText.ForeColor = base.RequiredLabelForceColor; - } - } - } - - - } -} + /// 修改人: /// 修改日期: /// 修改备注: - /// 版本:1.0 - /// - /// The format string. - public void TextFormat(string formatString) - { - if (!string.IsNullOrWhiteSpace(formatString)) - { - this.txtEdit.Properties.Mask.EditMask = "##########" + (formatString == "#" ? "0" : formatString);//#代表位数 - this.txtEdit.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric; - this.txtEdit.Properties.Mask.UseMaskAsDisplayFormat = true; - } - } - - - - - - } -} \ No newline at end of file + /// 版本: \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelTipWithLink.Designer.cs b/插件库/Lskj.Control/LabelTipWithLink.Designer.cs new file mode 100644 index 0000000..1e5a2b0 --- /dev/null +++ b/插件库/Lskj.Control/LabelTipWithLink.Designer.cs @@ -0,0 +1,29 @@ + +namespace Lskj.Control +{ + partial class LabelTipWithLink + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/插件库/Lskj.Control/LabelWeigh.cs b/插件库/Lskj.Control/LabelWeigh.cs index 0bca135..97ab015 100644 --- a/插件库/Lskj.Control/LabelWeigh.cs +++ b/插件库/Lskj.Control/LabelWeigh.cs @@ -225,21 +225,4 @@ namespace Lskj.Control { if (!string.IsNullOrWhiteSpace(formatString)) { - this.txtEdit.Properties.Mask.EditMask = "##########" + (formatString == "#" ? "0" : formatString);//#代表位数 - this.txtEdit.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric; - this.txtEdit.Properties.Mask.UseMaskAsDisplayFormat = true; - } - } - /// - /// 按钮点击 - /// - /// - /// - private void btnRefresh_Click(object sender, EventArgs e) - { - if (ButtonClick != null) ButtonClick(this, e); - } - - - } -} + this.txtEdit.Properties.Mask.EditMask = "# \ No newline at end of file diff --git a/插件库/Lskj.Control/Model/AuditChangeLog.cs b/插件库/Lskj.Control/Model/AuditChangeLog.cs new file mode 100644 index 0000000..526160a --- /dev/null +++ b/插件库/Lskj.Control/Model/AuditChangeLog.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Data; +using Lskj.Business; +using Lskj.Business.Impl; +using Lskj.Core; +using Lskj.Data; + +namespace Lskj.Control.Model +{ + /// + /// 审核改动日志处理类。 + /// 用来比较单据主表原始数据和当前表头控件值,并把发生变化的字段写入 P_SystemAuditChangeLog。 + /// + public class AuditChangeLog + { + private const string TableName = "P_SystemAuditChangeLog"; + private const int MaxOrderNumberLength = 50; + private const int MaxTextLength = 500; + + + /// + /// 比较表头字段是否发生变化,并保存审核改动日志。 + /// 返回 false 时,errorMessage 会一次性返回所有未记录成功的字段。 + /// + /// 改动前数据(单表数据或者单据主表数据) + /// 控件 mycontrol + /// 单号 + /// 步骤号 + /// 登录人id + /// + public static bool SaveHeaderChangeLog(DataRow drBillInfoMsg, MyControl controlObj, string orderNumber, string stepCode, string operatorId) + { + if (SystemInfo.Instance.AuditChangeRecord) + { + CreateModificationRecordTable(); + string errorMessage = string.Empty; + + // 原始主表数据或控件对象为空时,没有可比较的数据,直接返回成功。 + if (drBillInfoMsg == null || controlObj == null || controlObj.ControlModels == null) + return true; + + List errorFields = new List(); + + // 遍历当前界面的表头控件模型,逐个比较可保存字段。 + foreach (ControlModel model in controlObj.ControlModels) + { + string currentFieldName = model == null ? string.Empty : model.FieldName; + try + { + // 只比较可保存、界面真实存在、原始主表行中也存在的普通字段。 + if (!CanCompare(model, drBillInfoMsg, controlObj)) + continue; + + // 旧值来自打开审核界面时加载出来的主表原始行。 + string oldValue = GetRowValue(drBillInfoMsg, model.FieldName); + + // 新值来自当前界面控件值,也就是用户修改后的值。 + string newValue = controlObj.GetControlValue(model); + if (newValue == "****") + continue; + + // 日期、数字、空值先做统一处理,避免显示格式不同造成误判。 + if (IsSameValue(oldValue, newValue)) + continue; + + // 字段确实发生变化后写入日志;相同单号、步骤、字段已存在时执行更新。 + SaveChangeLog(orderNumber, model.FieldName, oldValue, newValue, stepCode, operatorId); + } + catch (Exception ex) + { + // 单个字段记录失败时先收集错误,继续处理后续字段,最后一次性提示。 + errorFields.Add(GetErrorFieldName(model, currentFieldName) + "(" + ex.Message + ")"); + } + } + + if (errorFields.Count > 0) + { + errorMessage = "以下字段审核改动日志未记录:" + Environment.NewLine + string.Join(Environment.NewLine, errorFields.ToArray()); + MessageUtil.Show(errorMessage); + return false; + } + } + return true; + } + + /// + /// 判断控件字段是否需要参与改动比较。 + /// + private static bool CanCompare(ControlModel model, DataRow drBillInfoMsg, MyControl controlObj) + { + if (model == null) + return false; + + // 不保存的字段和图片控件不参与本次表头改动日志记录。 + if (!model.IsSave || + model.FieldType == ControlType.LabPic || + model.FieldType == ControlType.LabPicEx) + return false; + + if (string.IsNullOrWhiteSpace(model.FieldName)) + return false; + + // 当前界面上没有真实控件的字段不参与比较。 + if (controlObj.FindControl(model) == null) + return false; + + // 原始主表行里必须存在同名数据库字段。 + return drBillInfoMsg.Table != null && drBillInfoMsg.Table.Columns.Contains(model.FieldName); + } + + /// + /// 保存单个字段的改动记录。 + /// 如果相同单号、相同步骤、相同字段已存在记录,则更新;否则新增。 + /// + private static void SaveChangeLog(string orderNumber, string fieldName, string oldValue, string newValue, string stepCode, string operatorId) + { + //orderNumber = orderNumber == null ? string.Empty : orderNumber; + //fieldName = fieldName == null ? string.Empty : fieldName; + //oldValue = oldValue == null ? string.Empty : oldValue; + //newValue = newValue == null ? string.Empty : newValue; + + //orderNumber = orderNumber.Length > MaxOrderNumberLength ? orderNumber.Substring(0, MaxOrderNumberLength) : orderNumber; + //fieldName = fieldName.Length > MaxTextLength ? fieldName.Substring(0, MaxTextLength) : fieldName; + //oldValue = oldValue.Length > MaxTextLength ? oldValue.Substring(0, MaxTextLength) : oldValue; + //newValue = newValue.Length > MaxTextLength ? newValue.Substring(0, MaxTextLength) : newValue; + + //orderNumber = orderNumber.Replace("'", "''"); + //fieldName = fieldName.Replace("'", "''"); + //oldValue = oldValue.Replace("'", "''"); + //newValue = newValue.Replace("'", "''"); + + string sql = string.Format(@"if exists (select 1 from {0} where orderNumber = '{1}' and stepCode = {2} and fieldName = N'{3}') + begin + update {0} + set oldValue = N'{4}', + newValue = N'{5}', + operatorId = N'{6}' + where orderNumber =N'{1}' + and stepCode = N'{2}' + and fieldName = N'{3}' + end + else + begin + insert into {0} (orderNumber, fieldName, oldValue, newValue, stepCode, operatorId) + values (N'{1}', N'{3}', N'{4}', N'{5}', N'{2}', N'{6}') + end", + TableName, + orderNumber, + stepCode, + fieldName, + oldValue, + newValue, + operatorId); + + SqlHelper.ExecuteNonQuery(sql); + } + + /// + /// 从原始主表行中读取字段旧值,数据库 NULL 统一按空字符串处理。 + /// + private static string GetRowValue(DataRow row, string fieldName) + { + if (row[fieldName] == DBNull.Value || row[fieldName] == null) + return string.Empty; + + return row[fieldName] + ""; + } + + /// + /// 获取错误提示中展示的字段名称,优先显示控件标题,没有标题时显示字段名。 + /// + private static string GetErrorFieldName(ControlModel model, string fieldName) + { + if (model != null && !string.IsNullOrWhiteSpace(model.LabelText)) + return model.LabelText + "[" + model.FieldName + "]"; + + return string.IsNullOrWhiteSpace(fieldName) ? "未知字段" : fieldName; + } + + /// + /// 判断两个值是否相同。 + /// 优先按日期、数字进行值比较,最后再按普通字符串比较。 + /// + private static bool IsSameValue(string oldValue, string newValue) + { + oldValue = NormalizeValue(oldValue); + newValue = NormalizeValue(newValue); + + if (oldValue == string.Empty && newValue == string.Empty) + return true; + + DateTime oldDate; + DateTime newDate; + if (DateTime.TryParse(oldValue, out oldDate) && DateTime.TryParse(newValue, out newDate)) + return oldDate == newDate; + + decimal oldDecimal; + decimal newDecimal; + if (decimal.TryParse(oldValue, out oldDecimal) && decimal.TryParse(newValue, out newDecimal)) + return oldDecimal == newDecimal; + + return oldValue == newValue; + } + + /// + /// 比较前统一处理 NULL 和首尾空格。 + /// + private static string NormalizeValue(string value) + { + return value == null ? string.Empty : value.Trim(); + } + + /// + /// 根据单号获取所有审核改动字段名。 + /// + /// 单号 + /// 当前单号对应的审核改动字段名集合 + public static List GetChangeLogFields(string orderNumber) + { + List fields = new List(); + if (SystemInfo.Instance.AuditChangeRecord) + { + CreateModificationRecordTable(); + orderNumber = orderNumber == null ? string.Empty : orderNumber.Replace("'", "''"); + + string sqlValue = string.Format(@" + select distinct fieldName + from {0} + where orderNumber = N'{1}' + order by fieldName", TableName, orderNumber); + + DataTable dataTable = SqlHelper.ExecuteDataTable(sqlValue); + + if (dataTable == null) + return fields; + + foreach (DataRow row in dataTable.Rows) + { + string fieldName = row["fieldName"] + ""; + if (!string.IsNullOrWhiteSpace(fieldName)) + fields.Add(fieldName); + } + + + } + return fields; + } + + /// + /// 创 \ No newline at end of file diff --git a/插件库/Lskj.Control/Model/GridExtend.cs b/插件库/Lskj.Control/Model/GridExtend.cs index ee2d3e9..513bd19 100644 --- a/插件库/Lskj.Control/Model/GridExtend.cs +++ b/插件库/Lskj.Control/Model/GridExtend.cs @@ -52,6 +52,7 @@ using DevExpress.Utils; using System.Data.Common; using DevExpress.Spreadsheet; using DevExpress.Docs; +using OfficeOpenXml; namespace Lskj.Control.Model { @@ -1187,7 +1188,13 @@ namespace Lskj.Control.Model dialog.FileName = menuName + DateTime.Now.ToString(SystemInfo.Instance.ExportFileDateFormat) + suffix; dialog.Filter = SystemInfo.Instance.IsXlsxFirst ? "Excel文件(*.xlsx)|*.xlsx|Excel文件(*.xls)|*.xls|PDF文件|*.PDF|RTF文件|*.RTF|HTML文件|*.html" : "Excel文件(*.xls)|*.xls|Excel文件(*.xlsx)|*.xlsx|PDF文件|*.PDF|RTF文件|*.RTF|HTML文件|*.html"; + if (SystemInfo.Instance.IsInsertWorksheet) dialog.OverwritePrompt = false; // 不弹系统“是否替换” + string FileName = string.Empty; DialogResult result = dialog.ShowDialog(); + if (!PrepareInsertWorksheetExport(dialog, menuName, result, ref FileName)) + { + return; + } if (result == DialogResult.OK) { WaitForm.ShowForm("导出中,请稍后..."); @@ -1254,6 +1261,10 @@ namespace Lskj.Control.Model if (bandedGridControlEx.gridControl.Tag is PanelControl) panel = bandedGridControlEx.gridControl.Tag as PanelControl; SetModuleName(dialog.FileName, fileExt, gridView.Columns.Cast().Count(column => column.Visible), true, panel); } + if (SystemInfo.Instance.IsInsertWorksheet && !string.IsNullOrWhiteSpace(FileName)) + { + AppendWorksheetToExcel(dialog.FileName, FileName); + } MessageUtil.Show(ResourceKeys.ExportSuccess); } catch (Exception ex) @@ -1297,11 +1308,21 @@ namespace Lskj.Control.Model dialog.Filter = SystemInfo.Instance.IsXlsxFirst ? "Excel文件(*.xlsx)|*.xlsx|Excel文件(*.xls)|*.xls|PDF文件|*.PDF|RTF文件|*.RTF|HTML文件|*.html" : "Excel文件(*.xls)|*.xls|Excel文件(*.xlsx)|*.xlsx|PDF文件|*.PDF|RTF文件|*.RTF|HTML文件|*.html"; + + if (SystemInfo.Instance.IsInsertWorksheet) dialog.OverwritePrompt = false; // 不弹系统“是否替换” + string FileName = string.Empty; + DialogResult result = dialog.ShowDialog(); + + if (!PrepareInsertWorksheetExport(dialog, menuName, result, ref FileName)) + { + return; + } + + if (result == DialogResult.OK) { WaitForm.ShowForm("导出中,请稍后..."); - try { //获取设置的导出列 @@ -1490,6 +1511,12 @@ namespace Lskj.Control.Model SetModuleName(dialog.FileName, fileExt, gridView.Columns.Cast().Count(column => column.Visible), false, panel); } + if (SystemInfo.Instance.IsInsertWorksheet &&!string.IsNullOrWhiteSpace(FileName)) + { + AppendWorksheetToExcel(dialog.FileName, FileName); + } + + MessageUtil.Show(ResourceKeys.ExportSuccess); } catch (Exception ex) @@ -1765,8 +1792,14 @@ namespace Lskj.Control.Model dialog.Title = "导出"; dialog.FileName = menuName + DateTime.Now.ToString(SystemInfo.Instance.ExportFileDateFormat) + ".xls"; dialog.Filter = "Excel文件(*.xls)|*.xls|Excel2007|*.xlsx|PDF文件|*.PDF|RTF文件|*.RTF|HTML文件|*.html"; + if (SystemInfo.Instance.IsInsertWorksheet) dialog.OverwritePrompt = false; // 不弹系统“是否替换” + string FileName = string.Empty; DialogResult result = dialog.ShowDialog(); + if (!PrepareInsertWorksheetExport(dialog, menuName, result, ref FileName)) + { + return; + } if (result == DialogResult.OK) { WaitForm.ShowForm("导出中,请稍后..."); @@ -1796,6 +1829,10 @@ namespace Lskj.Control.Model { control.ExportToHtml(dialog.FileName); } + if (SystemInfo.Instance.IsInsertWorksheet && !string.IsNullOrWhiteSpace(FileName)) + { + AppendWorksheetToExcel(dialog.FileName, FileName); + } MessageUtil.Show(ResourceKeys.ExportSuccess); } @@ -2092,8 +2129,6 @@ namespace Lskj.Control.Model - - /// /// 说明:获取GridView过滤或排序后的数据集 /// 创建人:龚宇超 @@ -2274,7 +2309,7 @@ namespace Lskj.Control.Model /// /// The col fields. /// 导入时是否触发关联计算(模块配置) - public static DataTable ToExcelDataTable(this GridView gridView, string fileName, string colFields, bool isDirectImport = false, bool isBillImport = false,bool AutoImportCalMode = false) + public static DataTable ToExcelDataTable(this GridView gridView, string fileName, string colFields, bool isDirectImport = false, bool isBillImport = false, bool AutoImportCalMode = false) { DataTable table = new DataTable(); int index = gridView is BandedGridView ? 1 : 0; @@ -2361,7 +2396,7 @@ namespace Lskj.Control.Model table.Columns.Add("lskjimport_errorFlag"); - bool AutoImportCal = SystemInfo.Instance.AutoImportCal|| AutoImportCalMode;//是否执行 关联和计算公式 + bool AutoImportCal = SystemInfo.Instance.AutoImportCal || AutoImportCalMode;//是否执行 关联和计算公式 //bool ImportDefaultValue= SystemInfo.Instance.ImportDefaultValue;//是否为空单元格添加默认值 //bool isImportRows = true;//是否是导入行(如果是合计行就不触发默认值) // 添加行 @@ -2392,7 +2427,7 @@ namespace Lskj.Control.Model col = index != 1 ? gridView.Columns.OfType().FirstOrDefault(x => Regex.Replace(x.Caption, @"\s", "") == Regex.Replace(headcell.ToString(), @"\s", "")) : newBandGrid.Columns.OfType().FirstOrDefault(x => Regex.Replace(x.OwnerBand + x.Caption, @"\s", "") == Regex.Replace(bandTitel + headcell.ToString(), @"\s", "")); if (col == null) continue; GridColumnModel model = col.Tag as GridColumnModel; - + if (cell != null) { if (cell.CellType == CellType.Error) @@ -2504,7 +2539,7 @@ namespace Lskj.Control.Model || model.FieldType == ControlType.LabAutoGridValue || model.FieldType == ControlType.LabAutoGridValueParam || model.FieldType == ControlType.LabSelectReturnId - || (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText)|| + || (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText) || model.FieldType == ControlType.LabModuleAddRowsID )) { @@ -2734,7 +2769,7 @@ namespace Lskj.Control.Model if (colFields.IndexOf("lskjimport_errorFlag") != -1 && !table.Columns.Contains("lskjimport_errorFlag")) table.Columns.Add("lskjimport_errorFlag"); - bool AutoImportCal = SystemInfo.Instance.AutoImportCal|| AutoImportCalMode;//是否执行 计算公式 + bool AutoImportCal = SystemInfo.Instance.AutoImportCal || AutoImportCalMode;//是否执行 计算公式 //bool ImportDefaultValue= SystemInfo.Instance.ImportDefaultValue;//是否为空单元格添加默认值 //bool isImportRows = true;//是否是导入行(如果是合计行就不触发默认值) // 添加行 @@ -2852,7 +2887,7 @@ namespace Lskj.Control.Model || model.FieldType == ControlType.LabAutoGridValue || model.FieldType == ControlType.LabAutoGridValueParam || model.FieldType == ControlType.LabSelectReturnId - || (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText)|| + || (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText) || model.FieldType == ControlType.LabModuleAddRowsID )) { @@ -3086,7 +3121,7 @@ namespace Lskj.Control.Model string fileName = dialog.FileName; string colFields = gridControlEx.GridView.Columns.ToString(','); - ImportTable = gridControlEx.GridView.ToExcelDataTable(fileName, colFields, true,false, SysModel.AutoImportCalMode); + ImportTable = gridControlEx.GridView.ToExcelDataTable(fileName, colFields, true, false, SysModel.AutoImportCalMode); if (ImportTable == null && ImportTable.Rows.Count < 1) @@ -3192,7 +3227,7 @@ namespace Lskj.Control.Model DbDataAdapter dat = BaseImpl.GetAdapterResult(sql); DbCommandBuilder cb = SqlHelper.dbFactory.CreateCommandBuilder(); cb.DataAdapter = dat; - // SqlCommandBuilder scb = new SqlCommandBuilder(dat); + // SqlCommandBuilder scb = new SqlCommandBuilder(dat); DataTable datatb = new DataTable(); DataTable failedData = new DataTable(); dat.Fill(datatb); @@ -3282,7 +3317,7 @@ namespace Lskj.Control.Model model.FieldType == ControlType.LabMultiSelectValueParam || model.FieldType == ControlType.LabAutoGridValue || model.FieldType == ControlType.LabSelectReturnId || - (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText)|| + (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText) || model.FieldType == ControlType.LabModuleAddRowsID )) { @@ -3699,7 +3734,7 @@ namespace Lskj.Control.Model || model.FieldType == ControlType.LabAutoGridValue || model.FieldType == ControlType.LabAutoGridValueParam || model.FieldType == ControlType.LabSelectReturnId - || (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText)|| + || (model.FieldType == ControlType.LabSelectReturnIdNew && model.ModuleFrameDisplayText) || model.FieldType == ControlType.LabModuleAddRowsID ) { @@ -3781,9 +3816,9 @@ namespace Lskj.Control.Model { string sqlValue = model.SqlSource; - if (model.FieldType == ControlType.LabSelectReturnId || model.FieldType == ControlType.LabSelectReturnIdNew|| model.FieldType == ControlType.LabModuleAddRowsID) + if (model.FieldType == ControlType.LabSelectReturnId || model.FieldType == ControlType.LabSelectReturnIdNew || model.FieldType == ControlType.LabModuleAddRowsID) { - if ((model.IsRadio && !string.IsNullOrWhiteSpace(model.addModuleld)) || model.FieldType == ControlType.LabSelectReturnIdNew|| model.FieldType == ControlType.LabModuleAddRowsID) + if ((model.IsRadio && !string.IsNullOrWhiteSpace(model.addModuleld)) || model.FieldType == ControlType.LabSelectReturnIdNew || model.FieldType == ControlType.LabModuleAddRowsID) { //单选模式数据源为模块sql 新版模块选中返回id固定位模块sql DataRow modelRow = Business.Impl.MainImpl.GetSystemdllTab(model.addModuleld); @@ -4089,4 +4124,495 @@ namespace Lskj.Control.Model // 设置填充模式为实心填充 cellStyle.FillPattern = FillPattern.SolidForeground; } - \ No newline at end of file + cell.CellStyle = cellStyle; + } + + + + + // 保存更改回原始文件 + using (FileStream file = new FileStream(excelFilePath, FileMode.Create, FileAccess.Write)) + { + workbook.Write(file); + } + } + catch (Exception ex) + { + + } + } + + + + /// + /// 是否存在未保存的数据 + /// + /// + /// + public static bool IsDataNotSaved(this GridControlEx control) + { + DataTable table = control.gridControl.DataSource as DataTable; + foreach (DataRow row in table.Rows) + { + if (row.RowState == DataRowState.Modified || row.RowState == DataRowState.Added) + { + return true; + } + } + + return false; + } + + + + /// + /// 准备追加工作表导出:用户选择已存在Excel文件时,先切换到临时文件导出,导出完成后再追加到原文件。 + /// + /// 保存文件对话框。 + /// 默认工作表名称。 + /// 保存文件对话框返回结果。 + /// 用户选择的原Excel文件路径。 + /// 是否继续导出。 + private static bool PrepareInsertWorksheetExport(SaveFileDialog dialog, string menuName, DialogResult result, ref string targetFileName) + { + if (result != DialogResult.OK || !SystemInfo.Instance.IsInsertWorksheet || !File.Exists(dialog.FileName)) + { + return true; + } + + string selectedFileExt = Path.GetExtension(dialog.FileName).ToLower(); + if (!selectedFileExt.Equals(".xlsx") && !selectedFileExt.Equals(".xls")) + { + MessageUtil.Show("追加工作表功能只支持.xls/.xlsx文件,请选择Excel文件。"); + return false; + } + + FrmSettingTableName frmSettingTableName = new FrmSettingTableName(menuName + DateTime.Now.ToString(SystemInfo.Instance.ExportFileDateFormat)); + if (frmSettingTableName.ShowDialog() != DialogResult.OK) + { + // 不导出 + return false; + } + + // 添加页签的形式导出:先保存原文件路径,再将当前导出路径切换到临时文件。 + targetFileName = dialog.FileName; + PubUtil.ClearFilesInDirectory(PubUtil.ExportFilePath); + string tempFileName = GetSafeExcelFileName(frmSettingTableName.TabName) + selectedFileExt; + dialog.FileName = Path.Combine(PubUtil.ExportFilePath, tempFileName); + return true; + } + + + /// + /// 将临时导出的Excel工作表追加到用户选择的Excel文件中。 + /// + /// 临时导出的Excel文件路径。 + /// 用户选择的原Excel文件路径。 + private static void AppendWorksheetToExcel(string sourceFileName, string targetFileName) + { + // 追加工作表只处理xlsx文件,避免xls/pdf/rtf/html走入不支持的合并逻辑。 + if (string.IsNullOrWhiteSpace(sourceFileName) || string.IsNullOrWhiteSpace(targetFileName)) + { + throw new Exception("追加工作表失败:文件路径不能为空。"); + } + if (!File.Exists(sourceFileName)) + { + throw new Exception("追加工作表失败:未找到临时导出文件。"); + } + if (!File.Exists(targetFileName)) + { + throw new Exception("追加工作表失败:未找到需要追加的Excel文件。"); + } + string fileExt = Path.GetExtension(targetFileName).ToLower(); + if (!Path.GetExtension(sourceFileName).ToLower().Equals(fileExt) || (!fileExt.Equals(".xlsx") && !fileExt.Equals(".xls"))) + { + throw new Exception("追加工作表失败:追加工作表功能只支持.xls/.xlsx文件。"); + } + + if (fileExt.Equals(".xls")) + { + AppendXlsWorksheetToExcel(sourceFileName, targetFileName); + return; + } + + // EPPlus 5及以上版本要求先设置LicenseContext,否则创建ExcelPackage时会报LicenseException。 + ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; + + FileInfo targetFileInfo = new FileInfo(targetFileName); + using (FileStream sourceStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (ExcelPackage sourcePackage = new ExcelPackage(sourceStream)) + using (ExcelPackage targetPackage = new ExcelPackage(targetFileInfo)) + { + ExcelWorksheet sourceSheet = GetFirstVisibleWorksheet(sourcePackage); + if (sourceSheet == null || sourceSheet.Dimension == null) + { + throw new Exception("追加工作表失败:临时导出文件中没有可追加的数据。"); + } + + // 使用临时文件名作为用户输入的工作表名称,并处理重名和Excel名称限制。 + string sheetName = GetUniqueWorksheetName(targetPackage, Path.GetFileNameWithoutExtension(sourceFileName)); + try + { + // 优先复制整个工作表,最大程度保留字体、边框、筛选、列宽等导出格式。 + targetPackage.Workbook.Worksheets.Add(sheetName, sourceSheet); + } + catch + { + // 整表复制失败时,退回到逐格复制,仍然尽量保留单元格样式。 + if (targetPackage.Workbook.Worksheets[sheetName] != null) + { + targetPackage.Workbook.Worksheets.Delete(sheetName); + } + ExcelWorksheet targetSheet = targetPackage.Workbook.Worksheets.Add(sheetName); + SafeCopyXlsxWorksheetContent(sourceSheet, targetSheet); + } + targetPackage.Save(); + } + + // 合并成功后删除临时文件,删除失败不影响导出结果。 + try + { + File.Delete(sourceFileName); + } + catch + { + } + } + + /// + /// 将临时导出的xls工作表追加到用户选择的xls文件中。 + /// + /// 临时导出的xls文件路径。 + /// 用户选择的原xls文件路径。 + private static void AppendXlsWorksheetToExcel(string sourceFileName, string targetFileName) + { + HSSFWorkbook sourceWorkbook; + HSSFWorkbook targetWorkbook; + + using (FileStream sourceStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + sourceWorkbook = new HSSFWorkbook(sourceStream); + } + + using (FileStream targetStream = new FileStream(targetFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + targetWorkbook = new HSSFWorkbook(targetStream); + } + + ISheet sourceSheet = GetFirstVisibleNpoiSheet(sourceWorkbook); + if (sourceSheet == null || sourceSheet.PhysicalNumberOfRows == 0) + { + throw new Exception("追加工作表失败:临时导出文件中没有可追加的数据。"); + } + + string sheetName = GetUniqueNpoiSheetName(targetWorkbook, Path.GetFileNameWithoutExtension(sourceFileName)); + ISheet targetSheet = targetWorkbook.CreateSheet(sheetName); + SafeCopyNpoiWorksheetContent(sourceSheet, targetSheet, targetWorkbook); + + using (FileStream targetStream = new FileStream(targetFileName, FileMode.Create, FileAccess.Write)) + { + targetWorkbook.Write(targetStream); + } + + // 合并成功后删除临时文件,删除失败不影响导出结果。 + try + { + File.Delete(sourceFileName); + } + catch + { + } + } + + /// + /// 获取源Excel中第一个可见且有数据的工作表。 + /// + /// Excel文件包。 + /// 可追加的工作表。 + private static ExcelWorksheet GetFirstVisibleWorksheet(ExcelPackage package) + { + foreach (ExcelWorksheet worksheet in package.Workbook.Worksheets) + { + if (worksheet != null && worksheet.Hidden == eWorkSheetHidden.Visible && worksheet.Dimension != null) + { + return worksheet; + } + } + return null; + } + + /// + /// 获取xls源文件中第一个可见且有数据的工作表。 + /// + /// xls工作簿。 + /// 可追加的工作表。 + private static ISheet GetFirstVisibleNpoiSheet(HSSFWorkbook workbook) + { + for (int i = 0; i < workbook.NumberOfSheets; i++) + { + if (!workbook.IsSheetHidden(i) && !workbook.IsSheetVeryHidden(i)) + { + ISheet sheet = workbook.GetSheetAt(i); + if (sheet != null && sheet.PhysicalNumberOfRows > 0) + { + return sheet; + } + } + } + return null; + } + + /// + /// 安全复制xlsx工作表内容,复制数据、样式、列宽、行高和合并区域。 + /// + /// 源工作表。 + /// 目标工作表。 + private static void SafeCopyXlsxWorksheetContent(ExcelWorksheet sourceSheet, ExcelWorksheet targetSheet) + { + int startRow = sourceSheet.Dimension.Start.Row; + int startCol = sourceSheet.Dimension.Start.Column; + int endRow = sourceSheet.Dimension.End.Row; + int endCol = sourceSheet.Dimension.End.Column; + + sourceSheet.Cells[startRow, startCol, endRow, endCol].Copy(targetSheet.Cells[startRow, startCol, endRow, endCol]); + + for (int row = startRow; row <= endRow; row++) + { + targetSheet.Row(row).Height = sourceSheet.Row(row).Height; + targetSheet.Row(row).Hidden = sourceSheet.Row(row).Hidden; + } + + for (int col = startCol; col <= endCol; col++) + { + targetSheet.Column(col).Width = sourceSheet.Column(col).Width; + targetSheet.Column(col).Hidden = sourceSheet.Column(col).Hidden; + } + + foreach (string address in sourceSheet.MergedCells) + { + if (!string.IsNullOrWhiteSpace(address)) + { + targetSheet.Cells[address].Merge = true; + } + } + + if (sourceSheet.View != null) + { + targetSheet.View.ShowGridLines = sourceSheet.View.ShowGridLines; + targetSheet.View.ZoomScale = sourceSheet.View.ZoomScale; + } + } + + /// + /// 安全复制xls工作表内容,复制数据、字体样式、列宽、行高和合并区域。 + /// + /// 源工作表。 + /// 目标工作表。 + /// 目标工作簿。 + private static void SafeCopyNpoiWorksheetContent(ISheet sourceSheet, ISheet targetSheet, HSSFWorkbook targetWorkbook) + { + int firstColumnIndex = -1; + int lastColumnIndex = -1; + Dictionary styleCache = new Dictionary(); + + for (int rowIndex = sourceSheet.FirstRowNum; rowIndex <= sourceSheet.LastRowNum; rowIndex++) + { + IRow sourceRow = sourceSheet.GetRow(rowIndex); + if (sourceRow == null) + { + continue; + } + + if (sourceRow.FirstCellNum >= 0) + { + firstColumnIndex = firstColumnIndex < 0 ? sourceRow.FirstCellNum : Math.Min(firstColumnIndex, sourceRow.FirstCellNum); + lastColumnIndex = Math.Max(lastColumnIndex, sourceRow.LastCellNum); + } + + IRow targetRow = targetSheet.CreateRow(rowIndex); + targetRow.Height = sourceRow.Height; + + for (int cellIndex = sourceRow.FirstCellNum; cellIndex < sourceRow.LastCellNum; cellIndex++) + { + if (cellIndex < 0) + { + continue; + } + + ICell sourceCell = sourceRow.GetCell(cellIndex); + if (sourceCell == null) + { + continue; + } + + ICell targetCell = targetRow.CreateCell(cellIndex); + CopyNpoiCellValue(sourceCell, targetCell); + CopyNpoiCellStyle(sourceCell, targetCell, targetWorkbook, styleCache); + } + } + + if (firstColumnIndex >= 0 && lastColumnIndex > firstColumnIndex) + { + for (int colIndex = firstColumnIndex; colIndex < lastColumnIndex; colIndex++) + { + targetSheet.SetColumnWidth(colIndex, sourceSheet.GetColumnWidth(colIndex)); + } + } + + for (int i = 0; i < sourceSheet.NumMergedRegions; i++) + { + CellRangeAddress sourceRange = sourceSheet.GetMergedRegion(i); + if (sourceRange != null) + { + targetSheet.AddMergedRegion(new CellRangeAddress( + sourceRange.FirstRow, + sourceRange.LastRow, + sourceRange.FirstColumn, + sourceRange.LastColumn)); + } + } + } + + /// + /// 复制xls单元格的值。 + /// + /// 源单元格。 + /// 目标单元格。 + private static void CopyNpoiCellValue(ICell sourceCell, ICell targetCell) + { + switch (sourceCell.CellType) + { + case CellType.Boolean: + targetCell.SetCellValue(sourceCell.BooleanCellValue); + break; + case CellType.Numeric: + targetCell.SetCellValue(sourceCell.NumericCellValue); + break; + case CellType.String: + targetCell.SetCellValue(sourceCell.StringCellValue); + break; + case CellType.Formula: + targetCell.SetCellFormula(sourceCell.CellFormula); + break; + case CellType.Error: + targetCell.SetCellErrorValue(sourceCell.ErrorCellValue); + break; + case CellType.Blank: + targetCell.SetCellType(CellType.Blank); + break; + default: + targetCell.SetCellValue(sourceCell.ToString()); + break; + } + } + + /// + /// 复制xls单元格样式和字体。 + /// + /// 源单元格。 + /// 目标单元格。 + /// 目标工作簿。 + /// 样式缓存,避免重复创建相同样式。 + private static void CopyNpoiCellStyle(ICell sourceCell, ICell targetCell, HSSFWorkbook targetWorkbook, Dictionary styleCache) + { + if (sourceCell.CellStyle == null) + { + return; + } + + short styleIndex = sourceCell.CellStyle.Index; + ICellStyle targetStyle = null; + if (!styleCache.TryGetValue(styleIndex, out targetStyle)) + { + targetStyle = targetWorkbook.CreateCellStyle(); + targetStyle.CloneStyleFrom(sourceCell.CellStyle); + + IFont sourceFont = sourceCell.CellStyle.GetFont(sourceCell.Sheet.Workbook); + if (sourceFont != null) + { + IFont targetFont = targetWorkbook.CreateFont(); + CopyNpoiFont(sourceFont, targetFont); + targetStyle.SetFont(targetFont); + } + + styleCache.Add(styleIndex, targetStyle); + } + + targetCell.CellStyle = targetStyle; + } + + /// + /// 复制xls字体属性。 + /// + /// 源字体。 + /// 目标字体。 + private static void CopyNpoiFont(IFont sourceFont, IFont targetFont) + { + targetFont.FontName = sourceFont.FontName; + targetFont.FontHeight = sourceFont.FontHeight; + targetFont.FontHeightInPoints = sourceFont.FontHeightInPoints; + targetFont.Boldweight = sourceFont.Boldweight; + targetFont.Color = sourceFont.Color; + targetFont.IsItalic = sourceFont.IsItalic; + targetFont.IsStrikeout = sourceFont.IsStrikeout; + targetFont.Underline = sourceFont.Underline; + targetFont.TypeOffset = sourceFont.TypeOffset; + targetFont.Charset = sourceFont.Charset; + } + + /// + /// 获取不重复且符合Excel规则的工作表名称。 + /// + /// 目标Excel文件包。 + /// 原始工作表名称。 + /// 可用的工作表名称。 + private static string GetUniqueWorksheetName(ExcelPackage package, string sheetName) + { + string baseName = GetSafeWorksheetName(sheetName); + string result = baseName; + int index = 1; + while (package.Workbook.Worksheets.Any(item => string.Equals(item.Name, result, StringComparison.OrdinalIgnoreCase))) + { + string suffix = "_" + index++; + int maxLength = 31 - suffix.Length; + string namePrefix = baseName.Length > maxLength ? baseName.Substring(0, maxLength) : baseName; + result = namePrefix + suffix; + } + return result; + } + + /// + /// 获取xls中不重复且符合Excel规则的工作表名称。 + /// + /// 目标xls工作簿。 + /// 原始工作表名称。 + /// 可用的工作表名称。 + private static string GetUniqueNpoiSheetName(HSSFWorkbook workbook, string sheetName) + { + string baseName = GetSafeWorksheetName(sheetName); + string result = baseName; + int index = 1; + while (workbook.GetSheet(result) != null) + { + string suffix = "_" + index++; + int maxLength = 31 - suffix.Length; + string namePrefix = baseName.Length > maxLength ? baseName.Substring(0, maxLength) : baseName; + result = namePrefix + suffix; + } + return result; + } + + /// + /// 获取符合Excel工作表命名规则的名称。 + /// + /// 原始工作表名称。 + /// 处理后的工作表名称。 + private static string GetSafeWorksheetName(string sheetName) + { + string result = (sheetName ?? string.Empty).Trim(); + char[] invalidChars = new char[] { '\\', '/', '?', '*', '[', ']', ':' }; + foreach (char invalidChar in invalidChars) + { + result = result.Replace(invalidChar, '_'); + } + result = Regex.Replace(result, \ No newline at end of file diff --git a/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs b/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs index fde48dc..907c8ef 100644 --- a/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs +++ b/插件库/Lskj.Control/Model/MenuStrip/BaseMenuStrip.cs @@ -932,6 +932,9 @@ namespace Lskj.Control.Model SqlStoredProcedurepPrompt.GenerateBillSaveScript_DM(SqlHelper.LastFailureSql); } } + string Message = ErrorMessage.PromptErrorMessage(ex); + MessageUtil.Show(Message, ex.Message); + return false; } finally { diff --git a/插件库/Lskj.Control/Model/MessageUtil.cs b/插件库/Lskj.Control/Model/MessageUtil.cs index 6278bd8..179ff32 100644 --- a/插件库/Lskj.Control/Model/MessageUtil.cs +++ b/插件库/Lskj.Control/Model/MessageUtil.cs @@ -38,14 +38,27 @@ namespace Lskj.Control /// public static DialogResult Show(string msg) { - if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在")) + if (msg.Contains("未将对象引用设置到对象的实例")) + { + try + { + string callStackInfo = GetBusinessCallStack(); + msg = "未将对象引用设置到对象的实例\r\n" + callStackInfo; + } + catch (Exception ex) + { + } + } + + if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在")&& !SystemInfo.Instance.PromptDeadlock) msg = "网络连接超时,请稍候再试!"; if (Business.Impl.LanguageTranslation.Translatable) { msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg); } + return XtraMessageBox.Show(msg, ResourceKeys.SystemTip, MessageBoxButtons.OK, MessageBoxIcon.Information); - + } /// @@ -58,9 +71,21 @@ namespace Lskj.Control /// 版本:1.0 /// /// - public static DialogResult Show(string msg, string errorMessage ) + public static DialogResult Show(string msg, string errorMessage) { - if (!string.IsNullOrEmpty(errorMessage) && errorMessage.Contains("与另一个进程被死锁在")) + if (errorMessage.Contains("未将对象引用设置到对象的实例")) + { + try + { + string callStackInfo = GetBusinessCallStack(); + errorMessage = "未将对象引用设置到对象的实例\r\n" + callStackInfo; + } + catch (Exception ex) + { + } + } + + if (!string.IsNullOrEmpty(errorMessage) && errorMessage.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock) { errorMessage = "网络连接超时,请稍候再试!"; if (Business.Impl.LanguageTranslation.Translatable) @@ -69,8 +94,8 @@ namespace Lskj.Control } return XtraMessageBox.Show(errorMessage, ResourceKeys.SystemTip, MessageBoxButtons.OK, MessageBoxIcon.Information); } - - if (!string.IsNullOrEmpty(errorMessage) && errorMessage.Contains("事务在触发器中结束。批处理已中止")) + + if (!string.IsNullOrEmpty(errorMessage) && errorMessage.Contains("事务在触发器中结束。批处理已中止")) { if (Business.Impl.LanguageTranslation.Translatable) { @@ -89,11 +114,11 @@ namespace Lskj.Control if (dr != DialogResult.Yes && !string.IsNullOrWhiteSpace(errorMessage)) { errorMessage = ErrorMessage.StackTrace; - if (SystemInfo.Instance.HideErrorSQL) + if (SystemInfo.Instance.HideErrorSQL) { - errorMessage= errorMessage.Split(new string[] { "SQL=[" }, StringSplitOptions.None)[0]; + errorMessage = errorMessage.Split(new string[] { "SQL=[" }, StringSplitOptions.None)[0]; } - XtraMessageBox.Show(errorMessage, ResourceKeys.SystemTip, MessageBoxButtons.OK, MessageBoxIcon.Information); + XtraMessageBox.Show(errorMessage, ResourceKeys.SystemTip, MessageBoxButtons.OK, MessageBoxIcon.Information); } DevExpress.XtraEditors.Controls.Localizer.Active = null; return DialogResult.OK; @@ -111,10 +136,32 @@ namespace Lskj.Control /// DialogResult. public static DialogResult Show(Exception ex) { + if (ex.Message.Contains("未将对象引用设置到对象的实例")) + { + try + { + //string callStackInfo = GetBusinessCallStack(); + //string msgnew = "未将对象引用设置到对象的实例\r\n" + callStackInfo; + + string errorInfo = $"【报错时间】:{DateTime.Now}\n" + + $"【异常类型】:{ex.GetType().Name}\n" + + $"【错误消息】:{ex.Message}\n" + + $"【报错方法】:{ex.TargetSite?.DeclaringType?.FullName}.{ex.TargetSite?.Name}\n" + + $"【完整调用栈】:\n{ex.StackTrace}\n" + + $"【内部异常】:{ex.InnerException?.Message}"; + + + return XtraMessageBox.Show(errorInfo, ResourceKeys.SystemTip, MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ) + { + } + } + if (Debugger.IsAttached) { string msg = ex == null ? ResourceKeys.UnKownErrorTip : ex.StackTrace; - if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在")) + if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock) msg = "网络连接超时,请稍候再试!"; if (Business.Impl.LanguageTranslation.Translatable) { @@ -125,7 +172,7 @@ namespace Lskj.Control else { string msg = ex == null ? ResourceKeys.UnKownErrorTip : ex.Message; //ResourceKeys.SystemErrorTip + "\r\n" + ex.Message + "\r\n" + ex.StackTrace; - if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在")) + if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock) msg = "网络连接超时,请稍候再试!"; if (Business.Impl.LanguageTranslation.Translatable) { @@ -155,8 +202,67 @@ namespace Lskj.Control /// The buttons. public static DialogResult Show(string msg, MessageBoxButtons buttons) { + + if (msg.Contains("未将对象引用设置到对象的实例")) + { + try + { + string callStackInfo = GetBusinessCallStack(); + msg = "未将对象引用设置到对象的实例\r\n" + callStackInfo; + } + catch (Exception ex) + { + } + } + if (Business.Impl.LanguageTranslation.Translatable) { msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg); } - return XtraMessageBox.Show(msg, ResourceKeys.SystemTip, buttons, M \ No newline at end of file + return XtraMessageBox.Show(msg, ResourceKeys.SystemTip, buttons, MessageBoxIcon.Information); + } + /// + /// 说明:弹出是否对话框 + /// 创建人:龚宇超 + /// 创建日期:2017-12-07 + /// 修改人: + /// 修改日期: + /// 修改备注: + /// 版本:1.0 + /// + /// The ex. + /// The buttons. + /// DialogResult. + public static DialogResult Show(Exception ex, MessageBoxButtons buttons) + { + string msg = ex == null ? "未知提示." : ex.StackTrace; + if (Business.Impl.LanguageTranslation.Translatable) + { + msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg); + } + return XtraMessageBox.Show(msg, ResourceKeys.SystemTip, buttons, MessageBoxIcon.Information); + } + + + + + + /// + /// 获取业务代码的调用栈(过滤框架/自身方法,只保留业务层调用) + /// + private static string GetBusinessCallStack() + { + try + { + // 创建堆栈跟踪,true 表示包含文件路径和行号(需生成pdb文件) + StackTrace stackTrace = new StackTrace(true); + StackFrame[] frames = stackTrace.GetFrames(); + + if (frames == null) return "无法获取调用栈"; + + // 过滤堆栈帧:跳过当前方法(GetBusinessCallStack)和 Show 方法,只保留业务调用层 + var businessFrames = frames + .SkipWhile(frame => + frame.GetMethod()?.DeclaringType == typeof(MessageUtil) // 跳过当前类的方法 + || frame.GetMethod()?.Module.ScopeName.StartsWith("System.") == true // 跳过系统框架方法 + || fr \ No newline at end of file diff --git a/插件库/Lskj.Control/Model/MyControl.cs b/插件库/Lskj.Control/Model/MyControl.cs index 872a671..1ee826a 100644 --- a/插件库/Lskj.Control/Model/MyControl.cs +++ b/插件库/Lskj.Control/Model/MyControl.cs @@ -159,6 +159,11 @@ namespace Lskj.Control.Model /// public string BillSourceControlId = string.Empty; + /// + /// 保存验证条件表 + /// + public DataTable SaveCondTab = new DataTable(); + /// /// 执行查询之前验证 @@ -1648,7 +1653,7 @@ namespace Lskj.Control.Model { SetControlValue(model, this.ParentKey); } - else if (model.RememberValue&& ConditionalCaching.ConditionalCaches.ContainsKey(model.id) && !string.IsNullOrWhiteSpace(ConditionalCaching.ConditionalCaches[model.id])) + else if (model.RememberValue && ConditionalCaching.ConditionalCaches.ContainsKey(model.id) && !string.IsNullOrWhiteSpace(ConditionalCaching.ConditionalCaches[model.id])) { SetControlValue(model, ConditionalCaching.ConditionalCaches[model.id]); } @@ -1658,7 +1663,7 @@ namespace Lskj.Control.Model SetControlValue(model, defaultValue); } - + } //智能搜索框第一次加载时手动触发 @@ -1710,7 +1715,7 @@ namespace Lskj.Control.Model /// /// The row item. /// true if XXXX, false otherwise. - public void CopyControlValue(bool Association = true,bool refreshSearchSource = false) + public void CopyControlValue(bool Association = true, bool refreshSearchSource = false) { try { @@ -2898,6 +2903,27 @@ namespace Lskj.Control.Model /// 返回保存成功于否 public bool SaveBaseModuleData(string menuCode, string tableName, string primaryKey, ref string primaryValue, bool isAdd = true, string leftField = "", bool isTip = true, int newVer = 0) { + + if (this.SaveCondTab != null && this.SaveCondTab.Rows.Count > 0) + { + foreach (DataRow CondItem in SaveCondTab.Rows) + { + string condition = CondItem["condition"] + ""; + if (!string.IsNullOrWhiteSpace(condition)) + { + string cond = this.ReplaceControlValue(condition); + if (!ValidateCond(condition, null)) + { + MessageUtil.Show(string.IsNullOrWhiteSpace(CondItem["hintmsg"] + "") ? "条件验证失败" : CondItem["hintmsg"] + ""); + return false; + } + } + } + } + + + + string execSql = string.Empty; if (string.IsNullOrWhiteSpace(tableName)) { @@ -3383,13 +3409,20 @@ namespace Lskj.Control.Model } if (RememberRow) { - if (this.GridRowCount <= oldRowHandle && SystemInfo.Instance.DeleteSelectedEndOf) + if (this._mainGridEx.GridView.OptionsSelection.MultiSelectMode == GridMultiSelectMode.CheckBoxRowSelect) { - oldRowHandle = this.GridRowCount - 1; + //多选框不选中,但滚动条移动到上一次点击的行 + if (oldRowHandle >= 0 && oldRowHandle < this._mainGridEx.GridView.RowCount) + this._mainGridEx.GridView.MakeRowVisible(oldRowHandle); + } + else + { + if (this.GridRowCount <= oldRowHandle && SystemInfo.Instance.DeleteSelectedEndOf) + { + oldRowHandle = this.GridRowCount - 1; + } + SetFocusedRowHandle(oldRowHandle); } - - SetFocusedRowHandle(oldRowHandle); - //SetTopRowHandle(oldTopRowHandle); } //执行删除或者右键后,主表没有数据时清空明细表格数据 if (this.GridRowCount == 0 && OnLastQueryTriggered != null) OnLastQueryTriggered(null, null); @@ -3490,11 +3523,20 @@ namespace Lskj.Control.Model } if (RememberRow) { - if (this.GridRowCount <= oldRowHandle && SystemInfo.Instance.DeleteSelectedEndOf) + if (this._mainGridEx.GridView.OptionsSelection.MultiSelectMode == GridMultiSelectMode.CheckBoxRowSelect) { - oldRowHandle = this.GridRowCount - 1; + //多选框不选中,但滚动条移动到上一次点击的行 + if (oldRowHandle >= 0 && oldRowHandle < this._mainGridEx.GridView.RowCount) + this._mainGridEx.GridView.MakeRowVisible(oldRowHandle); + } + else + { + if (this.GridRowCount <= oldRowHandle && SystemInfo.Instance.DeleteSelectedEndOf) + { + oldRowHandle = this.GridRowCount - 1; + } + SetFocusedRowHandle(oldRowHandle); } - SetFocusedRowHandle(oldRowHandle); } } } @@ -3546,11 +3588,20 @@ namespace Lskj.Control.Model } if (RememberRow) { - if (this.GridRowCount <= oldRowHandle && SystemInfo.Instance.DeleteSelectedEndOf) + if (this._mainGridEx.GridView.OptionsSelection.MultiSelectMode == GridMultiSelectMode.CheckBoxRowSelect) { - oldRowHandle = this.GridRowCount - 1; + //多选框不选中,但滚动条移动到上一次点击的行 + if (oldRowHandle >= 0 && oldRowHandle < this._mainGridEx.GridView.RowCount) + this._mainGridEx.GridView.MakeRowVisible(oldRowHandle); + } + else + { + if (this.GridRowCount <= oldRowHandle && SystemInfo.Instance.DeleteSelectedEndOf) + { + oldRowHandle = this.GridRowCount - 1; + } + SetFocusedRowHandle(oldRowHandle); } - SetFocusedRowHandle(oldRowHandle); } } } @@ -4265,6 +4316,9 @@ namespace Lskj.Control.Model { dateEdit.TextEdit.Properties.VistaCalendarViewStyle = DevExpress.XtraEditors.VistaCalendarViewStyle.YearView; } + + //dateEdit.TextEdit.Properties.Appearance.BackColor = ColorTranslator.FromHtml("#00FF00"); + baseControl = dateEdit; break; case ControlType.LabDateHalfDay: @@ -4351,6 +4405,7 @@ namespace Lskj.Control.Model autoEdit.Button.Visible = true; autoEdit.RefreshDataSource += new EventHandler(OnLabelAutoGridLookRefreshDataSource); } + //autoEdit.TextEdit.Properties.Appearance.BackColor = ColorTranslator.FromHtml("#00FF00"); autoEdit.clickAfterEmpty = model.clickAfterEmpty; autoEdit.ValueMember = ControlType.LabAutoCompleteValue == model.FieldType || ControlType.LabAutoCompleteValueParam == model.FieldType ? model.ValueMember : model.TextMember; autoEdit.ValueField = model.ValueMember; @@ -4707,6 +4762,7 @@ namespace Lskj.Control.Model //设置了ModuleFrameDisplayText(显示text值),就把配置的模块sql传给model.SourceSql if (model.FieldType == ControlType.LabSelectReturnIdNew) { + model.ModuleFrameDisplayText = true; moduleReturnsIdNew.ModuleFrameDisplayText = true; model.SourceSql = moduleReturnsIdNew._lookUpForm.SysModel.MenuSql; } @@ -6303,4 +6359,36 @@ namespace Lskj.Control.Model LabelDateEdit dateEdit = controlObj as LabelDateEdit; value = dateEdit.TextEdit.EditValue == null ? dateEdit.EditText : dateEdit.TextEdit.DateTime.ToString("yyyy-MM-dd"); } - else if ( \ No newline at end of file + else if (controlObj is LabelCheckEdit) + { + LabelCheckEdit checkEdit = controlObj as LabelCheckEdit; + value = checkEdit.EditText; + } + else if (controlObj is LabelComboxEdit) + { + LabelComboxEdit autoEdit = controlObj as LabelComboxEdit; + value = autoEdit.EditValue; + } + else if (controlObj is LabelTextEdit) + { + LabelTextEdit textIntEdit = controlObj as LabelTextEdit; + if (textIntEdit != null) value = string.IsNullOrEmpty(textIntEdit.EditText) ? "0" : textIntEdit.EditText; + } + + defaultValue = defaultValue.Replace(item, value); + } + + } + } + return defaultValue; + } + + + + /// + /// 设置控件背景颜色(无需传入txt_ 内部已经追加) + /// + /// + public void SetBackgroundColor(string controlName) + { + \ No newline at end of file diff --git a/插件库/Lskj.Control/Model/SignaturePrinting.cs b/插件库/Lskj.Control/Model/SignaturePrinting.cs new file mode 100644 index 0000000..e355a08 --- /dev/null +++ b/插件库/Lskj.Control/Model/SignaturePrinting.cs @@ -0,0 +1,499 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Printing; +using System.IO; +using System.Net; +using System.Threading; +using System.Web; +using System.Windows.Forms; +using iTextSharp.text.pdf; +using Lskj.Util; +using O2S.Components.PDFView4NET; +using O2S.Components.PDFView4NET.Printing; + +namespace Lskj.Control.Model +{ + public class SignaturePrinting + { + private const string DefaultSignatureImageFileName = "signature.png"; + private const float DefaultSignatureWidth = 160f; + private const float DefaultSignatureOpacity = 1f; + + public static string PreviewByUrl(string pdfUrl) + { + return PreviewByUrls(new string[] { pdfUrl }); + } + + public static string PreviewByUrls(string pdfUrls) + { + return PreviewByUrls(SplitUrls(pdfUrls)); + } + + public static string PreviewByUrls(IEnumerable pdfUrls) + { + return PreviewByUrls(pdfUrls, null); + } + + public static string PreviewByUrls(IEnumerable pdfUrls, string signatureImagePath) + { + try + { + string previewFile = CreateSignedPreviewFile(pdfUrls, signatureImagePath); + ShowPreviewForm(previewFile); + return previewFile; + } + catch (Exception ex) + { + MessageUtil.Show("签章打印预览失败", ex.Message); + return string.Empty; + } + } + + public static string CreateSignedPreviewFile(IEnumerable pdfUrls, string signatureImagePath) + { + List urls = NormalizeUrls(pdfUrls); + if (urls.Count == 0) + { + throw new ArgumentException("未传入需要打印的PDF文件地址。"); + } + + string signatureImage = ResolveSignatureImagePath(signatureImagePath); + string tempPath = PubUtil.SignatureFilePath; + PubUtil.ClearFilesInDirectory(tempPath); + + List signedFiles = new List(); + for (int i = 0; i < urls.Count; i++) + { + string downloadedFile = DownloadPdf(urls[i], tempPath, i + 1); + string signedFile = Path.Combine(tempPath, "signed_" + (i + 1).ToString("000") + "_" + Path.GetFileName(downloadedFile)); + AddCenteredSignature(downloadedFile, signedFile, signatureImage, DefaultSignatureWidth, DefaultSignatureOpacity); + signedFiles.Add(signedFile); + } + + if (signedFiles.Count == 1) + { + return signedFiles[0]; + } + + string mergedFile = Path.Combine(tempPath, "signature_preview_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".pdf"); + MergePdfFiles(signedFiles, mergedFile); + return mergedFile; + } + + private static IEnumerable SplitUrls(string pdfUrls) + { + if (string.IsNullOrWhiteSpace(pdfUrls)) + { + return new string[0]; + } + + return pdfUrls.Split(new string[] { "\r\n", "\n", ";", "|" }, StringSplitOptions.RemoveEmptyEntries); + } + + private static List NormalizeUrls(IEnumerable pdfUrls) + { + List urls = new List(); + if (pdfUrls == null) + { + return urls; + } + + foreach (string item in pdfUrls) + { + if (!string.IsNullOrWhiteSpace(item)) + { + urls.Add(item.Trim()); + } + } + + return urls; + } + + private static string ResolveSignatureImagePath(string signatureImagePath) + { + string imagePath = signatureImagePath; + if (string.IsNullOrWhiteSpace(imagePath)) + { + imagePath = Path.Combine(PubUtil.PdfSignImagePath, DefaultSignatureImageFileName); + } + else if (!Path.IsPathRooted(imagePath)) + { + imagePath = Path.Combine(PubUtil.AbsolutelyPath, imagePath); + } + + if (File.Exists(imagePath)) + { + return imagePath; + } + + string[] extensions = new string[] { "*.png", "*.jpg", "*.jpeg", "*.bmp", "*.gif" }; + foreach (string extension in extensions) + { + string[] files = Directory.GetFiles(PubUtil.PdfSignImagePath, extension); + if (files.Length > 0) + { + return files[0]; + } + } + + throw new FileNotFoundException("未找到签章图片,请将签章图片放到:" + imagePath); + } + + private static string DownloadPdf(string sourceUrl, string tempPath, int index) + { + string fileName = GetSafePdfFileName(sourceUrl, index); + string localFile = Path.Combine(tempPath, "download_" + index.ToString("000") + "_" + fileName); + + if (File.Exists(sourceUrl)) + { + File.Copy(sourceUrl, localFile, true); + return localFile; + } + + Uri uri; + if (!Uri.TryCreate(sourceUrl, UriKind.Absolute, out uri)) + { + throw new ArgumentException("PDF文件地址无效:" + sourceUrl); + } + + TryEnableTls12(); + using (TimeoutWebClient client = new TimeoutWebClient()) + { + client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0"); + client.DownloadFile(uri, localFile); + } + + return localFile; + } + + private static string GetSafePdfFileName(string sourceUrl, int index) + { + string fileName = string.Empty; + Uri uri; + if (Uri.TryCreate(sourceUrl, UriKind.Absolute, out uri)) + { + fileName = HttpUtility.UrlDecode(Path.GetFileName(uri.LocalPath)); + } + else + { + fileName = Path.GetFileName(sourceUrl); + } + + if (string.IsNullOrWhiteSpace(fileName)) + { + fileName = "file_" + index.ToString("000") + ".pdf"; + } + + foreach (char invalidChar in Path.GetInvalidFileNameChars()) + { + fileName = fileName.Replace(invalidChar, '_'); + } + + if (!Path.GetExtension(fileName).Equals(".pdf", StringComparison.OrdinalIgnoreCase)) + { + fileName = Path.GetFileNameWithoutExtension(fileName) + ".pdf"; + } + + return fileName; + } + + private static void AddCenteredSignature(string inputPdfPath, string outputPdfPath, string signatureImagePath, float signatureWidth, float opacity) + { + using (PdfReader reader = new PdfReader(inputPdfPath)) + { + using (FileStream outputStream = new FileStream(outputPdfPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + PdfStamper stamper = null; + try + { + stamper = new PdfStamper(reader, outputStream); + for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++) + { + iTextSharp.text.Rectangle pageSize = reader.GetPageSizeWithRotation(pageIndex); + iTextSharp.text.Image signature = iTextSharp.text.Image.GetInstance(signatureImagePath); + float width = Math.Min(signatureWidth, pageSize.Width * 0.6f); + float height = width * signature.Height / signature.Width; + float left = pageSize.Left + (pageSize.Width - width) / 2f; + float bottom = pageSize.Bottom + (pageSize.Height - height) / 2f; + + signature.ScaleAbsolute(width, height); + signature.SetAbsolutePosition(left, bottom); + + PdfContentByte content = stamper.GetOverContent(pageIndex); + PdfGState state = new PdfGState(); + state.FillOpacity = opacity; + content.SaveState(); + content.SetGState(state); + content.AddImage(signature); + content.RestoreState(); + } + } + finally + { + if (stamper != null) + { + stamper.Close(); + } + } + } + } + } + + private static void MergePdfFiles(List pdfFiles, string outputPdfPath) + { + iTextSharp.text.Document document = null; + PdfCopy copy = null; + FileStream outputStream = null; + + try + { + outputStream = new FileStream(outputPdfPath, FileMode.Create, FileAccess.Write, FileShare.None); + for (int fileIndex = 0; fileIndex < pdfFiles.Count; fileIndex++) + { + using (PdfReader reader = new PdfReader(pdfFiles[fileIndex])) + { + if (document == null) + { + document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1)); + copy = new PdfCopy(document, outputStream); + document.Open(); + } + + for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++) + { + copy.AddPage(copy.GetImportedPage(reader, pageIndex)); + } + } + } + } + finally + { + if (document != null) + { + document.Close(); + } + else if (outputStream != null) + { + outputStream.Close(); + } + } + } + + private static void ShowPreviewForm(string pdfFile) + { + if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) + { + throw new InvalidOperationException("签章打印预览需要在UI线程调用。"); + } + + using (SignaturePreviewForm previewForm = new SignaturePreviewForm(pdfFile)) + { + Form owner = Form.ActiveForm; + if (owner != null && !owner.IsDisposed) + { + previewForm.ShowDialog(owner); + } + else + { + previewForm.ShowDialog(); + } + } + } + + private static void TryEnableTls12() + { + try + { + ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | (SecurityProtocolType)3072; + } + catch + { + } + } + + private class TimeoutWebClient : WebClient + { + public int Timeout { get; set; } + + public TimeoutWebClient() + { + Timeout = 60000; + } + + protected override WebRequest GetWebRequest(Uri address) + { + WebRequest request = base.GetWebRequest(address); + if (request != null) + { + request.Timeout = Timeout; + } + + return request; + } + } + + private class SignaturePreviewForm : Form + { + private readonly string _pdfFile; + private readonly PDFDocument _document; + private readonly PDFPageView _pageView; + private readonly ToolStripLabel _pageLabel; + + public SignaturePreviewForm(string pdfFile) + { + _pdfFile = pdfFile; + _document = new PDFDocument(); + _pageView = new PDFPageView(); + _pageLabel = new ToolStripLabel(); + + InitializeComponent(); + Load += OnFormLoad; + FormClosed += OnFormClosed; + } + + private void InitializeComponent() + { + Text = "签章打印预览"; + StartPosition = FormStartPosition.CenterScreen; + Width = 1000; + Height = 760; + + ToolStrip toolStrip = new ToolStrip(); + toolStrip.GripStyle = ToolStripGripStyle.Hidden; + toolStrip.Dock = DockStyle.Top; + + ToolStripButton printButton = new ToolStripButton("打印"); + printButton.Click += OnPrintClick; + ToolStripButton firstButton = new ToolStripButton("首页"); + firstButton.Click += OnFirstClick; + ToolStripButton prevButton = new ToolStripButton("上一页"); + prevButton.Click += OnPrevClick; + ToolStripButton nextButton = new ToolStripButton("下一页"); + nextButton.Click += OnNextClick; + ToolStripButton lastButton = new ToolStripButton("末页"); + lastButton.Click += OnLastClick; + ToolStripButton zoomOutButton = new ToolStripButton("缩小"); + zoomOutButton.Click += OnZoomOutClick; + ToolStripButton zoomInButton = new ToolStripButton("放大"); + zoomInButton.Click += OnZoomInClick; + + toolStrip.Items.Add(printButton); + toolStrip.Items.Add(new ToolStripSeparator()); + toolStrip.Items.Add(firstButton); + toolStrip.Items.Add(prevButton); + toolStrip.Items.Add(nextButton); + toolStrip.Items.Add(lastButton); + toolStrip.Items.Add(new ToolStripSeparator()); + toolStrip.Items.Add(zoomOutButton); + toolStrip.Items.Add(zoomInButton); + toolStrip.Items.Add(new ToolStripSeparator()); + toolStrip.Items.Add(_pageLabel); + + _document.PageLayout = PDFPageLayout.SinglePage; + _document.PageMode = PDFPageMode.UseNone; + + _pageView.Dock = DockStyle.Fill; + _pageView.Document = _document; + _pageView.PageDisplayLayout = PDFPageDisplayLayout.OneColumn; + _pageView.ZoomMode = PDFZoomMode.FitWidth; + _pageView.WorkMode = UserInteractiveWorkMode.None; + _pageView.BackColor = Color.White; + + Controls.Add(_pageView); + Controls.Add(toolStrip); + } + + private void OnFormLoad(object sender, EventArgs e) + { + _document.Load(_pdfFile); + _pageView.PageNumber = 0; + UpdatePageLabel(); + } + + private void OnFormClosed(object sender, FormClosedEventArgs e) + { + try + { + _document.Close(); + } + catch + { + } + } + + private void OnPrintClick(object sender, EventArgs e) + { + try + { + using (PrintDialog printDialog = new PrintDialog()) + { + printDialog.AllowSomePages = true; + printDialog.UseEXDialog = true; + printDialog.PrinterSettings = new PrinterSettings(); + + if (printDialog.ShowDialog(this) != DialogResult.OK) + { + return; + } + + PDFPrintSettings settings = new PDFPrintSettings(printDialog.PrinterSettings); + settings.DocumentName = Path.GetFileName(_pdfFile); + settings.AutoRotate = true; + settings.PageScaling = PageScaling.FitToPrinterMarginsProportional; + + PDFPrintContent content = PDFPrintContent.Page | PDFPrintContent.Annotations | PDFPrintContent.FormFields; + _document.Print(settings, content); + } + } + catch (Exception ex) + { + MessageUtil.Show("签章PDF打印失败", ex.Message); + } + } + + private void OnFirstClick(object sender, EventArgs e) + { + _pageView.GoToFirstPage(); + UpdatePageLabel(); + } + + private void OnPrevClick(object sender, EventArgs e) + { + _pageView.GoToPrevPage(); + UpdatePageLabel(); + } + + private void OnNextClick(object sender, EventArgs e) + { + _pageView.GoToNextPage(); + UpdatePageLabel(); + } + + private void OnLastClick(object sender, EventArgs e) + { + _pageView.GoToLastPage(); + UpdatePageLabel(); + } + + private void OnZoomOutClick(object sender, EventArgs e) + { + _pageView.ZoomMode = PDFZoomMode.Custom; + _pageView.Zoom = Math.Max(0.25d, _pageView.Zoom - 0.1d); + } + + private void OnZoomInClick(object sender, EventArgs e) + { + _pageView.ZoomMode = PDFZoomMode.Custom; + _pageView.Zoom = Math.Min(5d, _pageView.Zoom + 0.1d); + } + + private void UpdatePageLabel() + { + int pageCount = _document.PageCount; + int pageNumber = pageCount == 0 ? 0 : _pageView.PageNumber + 1; + _pageLabel.Text = "第 " + pageNumber + " / " + pageCount + " 页"; + } + } + } +} diff --git a/插件库/Lskj.Control/ModuleGridDetailEx.cs b/插件库/Lskj.Control/ModuleGridDetailEx.cs index f07cf84..b71283d 100644 --- a/插件库/Lskj.Control/ModuleGridDetailEx.cs +++ b/插件库/Lskj.Control/ModuleGridDetailEx.cs @@ -732,7 +732,7 @@ namespace Lskj.Control } if (rowItem != null && model != null) { - if (!string.IsNullOrEmpty(model.UnionModule) && (string.IsNullOrEmpty(model.UnionValue) && string.IsNullOrEmpty(model.UnionCond))) return; + if (!string.IsNullOrEmpty(model.UnionModule) && (string.IsNullOrEmpty(model.UnionValue) && string.IsNullOrEmpty(model.UnionCond))&& !model.IgnoreAssociatedFields) return; if (tabPage.Tag is FrmWebBrowser) { // 加载网页 @@ -822,19 +822,27 @@ namespace Lskj.Control //{ // searchSql= moduleGridEx.SearchObj.SetSearchSqlValue(searchSql); //} + GridView view = this.ModuleGridObj.GridControlObj.GridView; + //DataTable dataTable = MainImpl.GetDataTableResult(searchSql);//明细数据源 + if (model.DynamicDetails && rowItem.Table.Columns.Contains("DisplayColumns")) + { + this.tcButtom.SetGridDisplayColumns(tabPage, rowItem["DisplayColumns"] + ""); + } + + //2026-4-24赵坤 先根据选中行改变条件,后续明细sql拼接上条件(之前修改条件后不会拼接到sql中) + if (tabPage.Tag is GridControlEx && (tabPage.Tag as GridControlEx).ParentControl != null) + { + (tabPage.Tag as GridControlEx).ParentControl.SetAllControlValue(rowItem); + if(model.DetailSearch) searchSql = (tabPage.Tag as GridControlEx).ParentControl.SetSearchSqlValue(searchSql); + } + //记录上一次执行的sql if (tabPage.Tag is GridControlEx) { (tabPage.Tag as GridControlEx).LastSearchSql = searchSql; } - GridView view = this.ModuleGridObj.GridControlObj.GridView; - //DataTable dataTable = MainImpl.GetDataTableResult(searchSql);//明细数据源 - if (model.DynamicDetails && rowItem.Table.Columns.Contains("DisplayColumns")) // - { - this.tcButtom.SetGridDisplayColumns(tabPage, rowItem["DisplayColumns"] + ""); - } + this.tcButtom.SetGridDataSource(tabPage, MainImpl.GetDataTableResult(searchSql), view); - if (tabPage.Tag is GridControlEx && (tabPage.Tag as GridControlEx).ParentControl != null) - (tabPage.Tag as GridControlEx).ParentControl.SetAllControlValue(rowItem); + //配置明细直接根据条件加载 if (model.SystemModel != null && 1 == model.SystemModel.isFirstLoad) { @@ -1001,7 +1009,7 @@ namespace Lskj.Control } - if (ReplaceHelper.IsSelect(sqlValue) && !string.IsNullOrEmpty(model.UnionValue)) + if (ReplaceHelper.IsSelect(sqlValue) && !string.IsNullOrEmpty(model.UnionValue))//ReplaceHelper.IsSelect { string Conditions = string.Empty; //是左侧选中行,并且没有替换字段,则使用主表选中行 diff --git a/插件库/Lskj.Control/ModuleGridEx.cs b/插件库/Lskj.Control/ModuleGridEx.cs index 461dbe0..4da7e8a 100644 --- a/插件库/Lskj.Control/ModuleGridEx.cs +++ b/插件库/Lskj.Control/ModuleGridEx.cs @@ -140,6 +140,12 @@ namespace Lskj.Control /// 高级查询条件设置 /// private DataTable _schemesTable = new DataTable(); + + /// + /// 保存验证条件表 + /// + public DataTable SaveCondTab = new DataTable(); + /// /// 判断明细是否是拖拽中 /// @@ -209,6 +215,9 @@ namespace Lskj.Control /// 浏览器添加行是否成功 /// public bool BrowserAddRow = false; + + + #endregion #region public set property @@ -690,7 +699,7 @@ namespace Lskj.Control } - if(tableCommon.Rows.Count>0) this.pl_buttom.Visible = true; + if (tableCommon.Rows.Count > 0) this.pl_buttom.Visible = true; this.dpbTools.Visible = tableCommon != null && pm_common.ItemLinks.Count > 0; this.dpbTools.Click += DpbTools_Click; //this.dpbTools.Location = new Point(x + 6, 6); @@ -780,7 +789,7 @@ namespace Lskj.Control { SimpleButton btn = sender as SimpleButton; DataRow rowItem = btn.Tag as DataRow; - CommonMenu menu = new CommonMenu(this.Model, this.SearchObj,this.GridControlObj); + CommonMenu menu = new CommonMenu(this.Model, this.SearchObj, this.GridControlObj); StaticControl.RightMenuGridView = gcMain.GridView; StaticControl.Comprefix = this.SysModel.PrefixKey; menu.Apply(rowItem); @@ -796,7 +805,7 @@ namespace Lskj.Control this.BrowserAddRow = false; //新增一行 this.AddGridViewRecord(); - if (this.gcMain.GridView.FocusedRowHandle == rowNumber&& BrowserAddRow) + if (this.gcMain.GridView.FocusedRowHandle == rowNumber && BrowserAddRow) { //成功新增行,把网页返回的行赋值 foreach (GridColumn col in gridColumns) @@ -1088,7 +1097,7 @@ namespace Lskj.Control dtGridRowColors = BaseModuleImpl.GetBaseGridRowColors(this.Model.ModuleCode); } this.gcMain.SetGridRowColors(dtGridRowColors); - + if (!dataCaches.GetValue(this, "BaseGridRightMenus", out DataTable dt)) { dt = BaseModuleImpl.GetBaseGridRightMenus(this.Model.ModuleCode); @@ -2122,7 +2131,7 @@ namespace Lskj.Control private void OnAfterLinkCilkCall(object sender, EventArgs e) { string unioright = sender + ""; - + DataRow rightrowitem = this.GridControlObj.gridViewRightMenu.MenuTable.Rows.Cast().FirstOrDefault(x => (x["orderid"] + "").Equals(unioright)); GridRightMenuModel model = new GridRightMenuModel(rightrowitem); DataRow rowItem = this.GridControlObj.GetViewFocusedDataRow(); @@ -3765,6 +3774,14 @@ namespace Lskj.Control this._gridAllColumns = BaseModuleImpl.GetBaseGridAllColumns(this.Model.ModuleCode); } + if (!dataCaches.GetValue(this, "SaveCondTab", out this.SaveCondTab)) + { + this.SaveCondTab = BaseModuleImpl.GetClientCond(this.Model.ModuleCode); + } + + + + if (this.SearchObj != null) { this.SearchObj.SystemModel = sysModel; @@ -3965,6 +3982,12 @@ namespace Lskj.Control { return BaseModuleImpl.GetBaseGridAllColumns(dynamicModel.ModuleCode); })); + + Task saveCondTabTask = cachesDic.AddTask(this, "SaveCondTab", new Task(() => + { + return BaseModuleImpl.GetClientCond(dynamicModel.ModuleCode); + })); + Task baseGridColumnsTask = cachesDic.AddTask(this, "BaseGridColumns", new Task(() => { return BaseModuleImpl.GetBaseGridColumns(dynamicModel.ModuleCode); @@ -4506,12 +4529,12 @@ namespace Lskj.Control try { GridColumn gridColumn = this.gcMain.GridView.FocusedColumn; - if (gridColumn != null&&!gridColumn.FieldName.Equals("DX$CheckboxSelectorColumn")) + if (gridColumn != null && !gridColumn.FieldName.Equals("DX$CheckboxSelectorColumn")) { //双击的是url图片框就不打开修改界面(会打开图片框) GridColumnModel columnModel = gridColumn.Tag as GridColumnModel; - if (columnModel.FieldType == ControlType.LabPicUrl) return; - + if (columnModel != null && columnModel.FieldType == ControlType.LabPicUrl) return; + } if (!string.IsNullOrWhiteSpace(this.SysModel.PreSQL))//如果配置预新增界面则弹出 @@ -4688,6 +4711,39 @@ namespace Lskj.Control return; } } + + if (this.SaveCondTab != null && this.SaveCondTab.Rows.Count > 0) + { + //获取新增和修改行 + DataRow[] modifiedRows = this.gcMain is TreeGridControlEx ? ((gcMain as TreeGridControlEx).TreeListObj.DataSource as DataTable) + .Rows + .Cast() + .Where(x => x.RowState == DataRowState.Modified || x.RowState == DataRowState.Added) + .ToArray() : (gcMain.GridControl.DataSource as DataTable) + .Rows + .Cast() + .Where(x => x.RowState == DataRowState.Modified || x.RowState == DataRowState.Added) + .ToArray(); + + foreach (DataRow CondItem in SaveCondTab.Rows) + { + string condition = CondItem["condition"] + ""; + if (!string.IsNullOrWhiteSpace(condition)) + { + foreach (DataRow item in modifiedRows) + { + if (!ValidateCond(condition, item)) + { + MessageUtil.Show(string.IsNullOrWhiteSpace(CondItem["hintmsg"] + "") ? "条件验证失败" : CondItem["hintmsg"] + ""); + return; + } + } + } + } + } + + + if (this.gcMain is TreeGridControlEx) { bool isExec = true; @@ -4725,7 +4781,7 @@ namespace Lskj.Control { } - IsApi: if (isExec) + IsApi: if (isExec) { this.SaveTreeRecord(); if (OnSaveGridCallBack != null) @@ -4786,7 +4842,7 @@ namespace Lskj.Control { LogUtil.WriteError("基础档案明细保存失败", ex); } - IsApi: if (isExec) + IsApi: if (isExec) { this.SaveGridRecord(); if (OnSaveGridCallBack != null) @@ -5218,11 +5274,11 @@ namespace Lskj.Control { (this.gcMain as TreeGridControlEx).RefreshDataSource(); } - else + else { this.gcMain.RefreshDataSource(); } - + //刷新子模块表格 if (AfterRefreshingCallBack != null) AfterRefreshingCallBack(sender, e); } @@ -5690,7 +5746,7 @@ namespace Lskj.Control GridRightMenuModel model = new GridRightMenuModel(rightRow); if (!string.IsNullOrEmpty(model.MenuCond)) { - item.Enabled = ValidateCond(model.MenuCond, rowItem); + item.Enabled = ValidateCond(model.MenuCond, rowItem); } } } @@ -5971,7 +6027,7 @@ namespace Lskj.Control /// /// /// - public void AddGridRows(string FieldName, List list) + public void AddGridRows(string FieldName, List list) { if (string.IsNullOrWhiteSpace(this.SysModel.MenuAddName)) { diff --git a/插件库/Lskj.Control/ModulePanelEx.cs b/插件库/Lskj.Control/ModulePanelEx.cs index 083096a..f0733d7 100644 --- a/插件库/Lskj.Control/ModulePanelEx.cs +++ b/插件库/Lskj.Control/ModulePanelEx.cs @@ -347,6 +347,8 @@ namespace Lskj.Control btnAdd.Enabled = string.IsNullOrWhiteSpace(this.PrimaryValue) && "0".Equals(IsView); // 配置有流转步骤(显示)、配置按钮可用、有权限时 可用 btnApply.Enabled = (this.SysModel.SaveApplyEnable || !string.IsNullOrWhiteSpace(this.PrimaryValue)) && "0".Equals(IsView) && BaseModuleImpl.HasStepFlow(this.Model.ModuleCode); + + // 常用打印 this.InitializePrintFile(); // 常用工具 @@ -788,6 +790,9 @@ namespace Lskj.Control popUpDyncModel = this.Model, Model = this.Model }; + + this.ControlObj.SaveCondTab= BaseModuleImpl.GetClientCond(this.Model.ModuleCode); + this.SetButtonPanelVisible("lskj.pubadd4.dll".Equals(this.SysModel.MenuAddName.ToLower())); bool topVisible = false; if ("lskj.pubadd.dll".Equals((this.SysModel.MenuAddName).ToLower()) || "lskj.pubadd2.dll".Equals((this.SysModel.MenuAddName).ToLower())) diff --git a/插件库/Lskj.Control/SpecialDate/SpecialDatePopup.cs b/插件库/Lskj.Control/SpecialDate/SpecialDatePopup.cs new file mode 100644 index 0000000..15f5ed1 --- /dev/null +++ b/插件库/Lskj.Control/SpecialDate/SpecialDatePopup.cs @@ -0,0 +1,186 @@ +using DevExpress.XtraEditors; +using DevExpress.XtraEditors.Controls; +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace Lskj.Control.SpecialDate +{ + public class SpecialDatePopup : UserControl + { + private const string Morning = "\u4e0a\u5348"; + private const string Afternoon = "\u4e0b\u5348"; + + private readonly CalendarControl calendar; + private readonly RadioGroup halfDayRadio; + private readonly SimpleButton btnOk; + private readonly SimpleButton btnClear; + private readonly SimpleButton btnCancel; + + // 弹出层不直接操作表格,只把按钮动作通知给 GridControlEx。 + public event EventHandler ConfirmClick; + public event EventHandler ClearClick; + public event EventHandler CancelClick; + + // 当前正在编辑的表格下拉编辑器,由 GridControlEx 在 QueryPopUp 时赋值。 + public PopupContainerEdit OwnerEdit { get; set; } + + public SpecialDatePopup() + { + this.calendar = new CalendarControl(); + this.halfDayRadio = new RadioGroup(); + this.btnOk = new SimpleButton(); + this.btnClear = new SimpleButton(); + this.btnCancel = new SimpleButton(); + + InitializeComponent(); + } + + public string SelectedValue + { + get + { + string halfDay = (this.halfDayRadio.EditValue + "").Equals(Afternoon) ? Afternoon : Morning; + return this.calendar.DateTime.ToString("yyyy-MM-dd") + " " + halfDay; + } + } + + // 打开下拉框时,根据当前单元格值回填日期和上午/下午。 + public void SetValue(string value) + { + DateTime date = DateTime.Today; + string halfDay = Morning; + + if (!string.IsNullOrWhiteSpace(value)) + { + string text = value.Trim(); + if (text.Contains(Afternoon)) + { + halfDay = Afternoon; + } + else if (text.Contains(Morning)) + { + halfDay = Morning; + } + + string dateText = text.Replace(Morning, "").Replace(Afternoon, "").Trim(); + DateTime parsedDate; + if (DateTime.TryParse(dateText, out parsedDate) || DateTime.TryParse(text, out parsedDate)) + { + date = parsedDate.Date; + // 兼容历史时间值,例如 2026-05-17 15:00:00 会默认识别为下午。 + if (!text.Contains(Morning) && !text.Contains(Afternoon)) + { + halfDay = parsedDate.Hour >= 12 ? Afternoon : Morning; + } + } + } + + this.calendar.DateTime = date; + this.halfDayRadio.EditValue = halfDay; + } + + private void InitializeComponent() + { + PanelControl rightPanel = new PanelControl(); + PanelControl bottomPanel = new PanelControl(); + LabelControl halfDayLabel = new LabelControl(); + + ((System.ComponentModel.ISupportInitialize)(rightPanel)).BeginInit(); + rightPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(bottomPanel)).BeginInit(); + bottomPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.halfDayRadio.Properties)).BeginInit(); + this.SuspendLayout(); + + this.Size = new Size(430, 260); + this.MinimumSize = this.Size; + + this.calendar.Dock = DockStyle.Fill; + // 这里不要 DevExpress 自带的时分秒编辑,只保留日期选择。 + this.calendar.CalendarTimeEditing = DevExpress.Utils.DefaultBoolean.False; + this.calendar.ShowTodayButton = true; + this.calendar.ShowClearButton = false; + + rightPanel.Dock = DockStyle.Right; + rightPanel.BorderStyle = BorderStyles.NoBorder; + rightPanel.Width = 110; + + halfDayLabel.Text = "\u65f6\u6bb5"; + halfDayLabel.Location = new Point(14, 18); + + // 右侧只提供上午/下午两个固定选项,保证保存字符串格式稳定。 + this.halfDayRadio.Location = new Point(12, 46); + this.halfDayRadio.Size = new Size(86, 70); + this.halfDayRadio.Properties.BorderStyle = BorderStyles.NoBorder; + this.halfDayRadio.Properties.Items.Add(new RadioGroupItem(Morning, Morning)); + this.halfDayRadio.Properties.Items.Add(new RadioGroupItem(Afternoon, Afternoon)); + this.halfDayRadio.EditValue = Morning; + + rightPanel.Controls.Add(this.halfDayRadio); + rightPanel.Controls.Add(halfDayLabel); + + bottomPanel.Dock = DockStyle.Bottom; + bottomPanel.BorderStyle = BorderStyles.NoBorder; + bottomPanel.Height = 36; + + this.btnOk.Text = "\u786e\u5b9a(&O)"; + this.btnOk.Size = new Size(72, 24); + this.btnOk.Location = new Point(180, 6); + this.btnOk.Click += OnOkClick; + + this.btnClear.Text = "\u6e05\u9664"; + this.btnClear.Size = new Size(72, 24); + this.btnClear.Location = new Point(260, 6); + this.btnClear.Click += OnClearClick; + + this.btnCancel.Text = "\u53d6\u6d88"; + this.btnCancel.Size = new Size(72, 24); + this.btnCancel.Location = new Point(340, 6); + this.btnCancel.Click += OnCancelClick; + + bottomPanel.Controls.Add(this.btnOk); + bottomPanel.Controls.Add(this.btnClear); + bottomPanel.Controls.Add(this.btnCancel); + + this.Controls.Add(this.calendar); + this.Controls.Add(rightPanel); + this.Controls.Add(bottomPanel); + + ((System.ComponentModel.ISupportInitialize)(this.halfDayRadio.Properties)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(bottomPanel)).EndInit(); + bottomPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(rightPanel)).EndInit(); + rightPanel.ResumeLayout(false); + rightPanel.PerformLayout(); + this.ResumeLayout(false); + } + + private void OnOkClick(object sender, EventArgs e) + { + // 通知 GridControlEx 写入 SelectedValue 并关闭下拉框。 + if (ConfirmClick != null) + { + ConfirmClick(this, EventArgs.Empty); + } + } + + private void OnClearClick(object sender, EventArgs e) + { + // 通知 GridControlEx 清空当前单元格。 + if (ClearClick != null) + { + ClearClick(this, EventArgs.Empty); + } + } + + private void OnCancelClick(object sender, EventArgs e) + { + // 通知 GridControlEx 只关闭下拉框,不改单元格值。 + if (CancelClick != null) + { + CancelClick(this, EventArgs.Empty); + } + } + } +} diff --git a/插件库/Lskj.Control/TabControlEx.cs b/插件库/Lskj.Control/TabControlEx.cs index 5901aaa..1ada6da 100644 --- a/插件库/Lskj.Control/TabControlEx.cs +++ b/插件库/Lskj.Control/TabControlEx.cs @@ -145,6 +145,20 @@ namespace Lskj.Control /// public Dictionary PageControlsDic = new Dictionary(); /// + /// 左右结构中,左侧表格与右侧页签的对应关系。 + /// 左侧重新绑定空数据源时不会触发行焦点变化事件,需要通过这个关系主动刷新右侧。 + /// + private readonly Dictionary _rightTabsByLeftGrid = new Dictionary(); + /// + /// 已经绑定过左右联动事件的左侧表格,避免重复绑定事件导致重复刷新。 + /// + private readonly HashSet _rightTabRefreshRegisteredGrids = new HashSet(); + /// + /// 左右结构中的右侧页签集合。 + /// 只有这些页签会根据数据行数禁用 ModuleGridEx 底部操作栏。 + /// + private readonly HashSet _rightSideTabPages = new HashSet(); + /// /// 页签名(判断是否有重复的左右结构) /// public string DetaiName = string.Empty; @@ -219,6 +233,22 @@ namespace Lskj.Control } return null; } + + /// + /// 设置当前页签内 ModuleGridEx 底部操作栏是否可交互。 + /// 只处理左右结构右侧页签里直接承载的 ModuleGridEx,不影响普通页签和左侧表。 + /// + private void SetModuleGridBottomPanelEnabled(XtraTabPage tabPage, bool enabled) + { + if (tabPage == null) return; + if (!_rightSideTabPages.Contains(tabPage)) return; + + ModuleGridEx moduleGrid = tabPage.Controls.OfType().FirstOrDefault(); + if (moduleGrid != null && moduleGrid.ObjPanel != null) + { + moduleGrid.ObjPanel.Enabled = enabled; + } + } #endregion #region ▼ 新核心方法 ▼ @@ -234,7 +264,12 @@ namespace Lskj.Control { /********* 0. 前置:获得模型对象 & 当前行 *********/ GridDetailModel model = ResolveModel(tabPage); - if (model == null) { BindTableToPage(tabPage, new DataTable()); return; } + if (model == null) + { + BindTableToPage(tabPage, new DataTable()); + SetModuleGridBottomPanelEnabled(tabPage, false); + return; + } // 行:优先 overrideRow,其次主表当前行 DataRow rowItem = overrideRow ?? leftGrid.GetViewFocusedDataRow(); @@ -257,10 +292,12 @@ namespace Lskj.Control sqlValue = ReplaceHelper.ReplaceWhereCond(sqlValue); DataTable dt = MainImpl.GetDataTableResult(sqlValue); BindTableToPage(tabPage, dt); + SetModuleGridBottomPanelEnabled(tabPage, dt != null && dt.Rows.Count > 0); } else { BindTableToPage(tabPage, new DataTable()); + SetModuleGridBottomPanelEnabled(tabPage, false); } return; } @@ -276,7 +313,12 @@ namespace Lskj.Control string orderIdStr = model.Orderid.ToString(); bool visible = numberList.Split(',').Contains(orderIdStr); tabPage.PageVisible = visible; - if (!visible) { BindTableToPage(tabPage, new DataTable()); return; } + if (!visible) + { + BindTableToPage(tabPage, new DataTable()); + SetModuleGridBottomPanelEnabled(tabPage, false); + return; + } } } @@ -357,6 +399,7 @@ namespace Lskj.Control DataTable table = MainImpl.GetDataTableResult(finalSql); BindTableToPage(tabPage, table, finalSql); + SetModuleGridBottomPanelEnabled(tabPage, table != null && table.Rows.Count > 0); tabPage.Text = $"{model.DetailName}({table.Rows.Count}条)"; tabPage.Appearance.Header.ForeColor = table.Rows.Count > 0 ? Color.Red : Color.FromArgb(0, 0, 0); // 首次加载自动查询 @@ -377,6 +420,23 @@ namespace Lskj.Control } #endregion + /// + /// 注册左右结构的联动刷新。 + /// 行焦点变化时刷新右侧,同时记录映射,便于左侧重新绑定空数据源后主动清空右侧。 + /// + private void RegisterRightTabRefresh(GridControlEx leftGrid, XtraTabControl rightTab) + { + if (leftGrid == null || rightTab == null) return; + + _rightTabsByLeftGrid[leftGrid] = rightTab; + if (!_rightTabRefreshRegisteredGrids.Contains(leftGrid)) + { + leftGrid.GridView.FocusedRowObjectChanged += (s, e) => RefreshRightTabAfterLeftBind(leftGrid); + _rightTabRefreshRegisteredGrids.Add(leftGrid); + } + RefreshRightTab(rightTab, leftGrid);// 首次加载 + } + /// 根据左侧选中行刷新右侧整个 TabControl。 private void RefreshRightTab(XtraTabControl rightTab, GridControlEx leftGrid) { @@ -388,6 +448,21 @@ namespace Lskj.Control SetTabPageDataSource(page, leftGrid, isNull, rowItem); } } + + /// + /// 左侧表格重新绑定数据源后主动刷新右侧。 + /// 解决空表没有焦点行变化事件,导致右侧表残留旧数据的问题。 + /// + private void RefreshRightTabAfterLeftBind(GridControlEx leftGrid) + { + if (leftGrid == null) return; + + if (_rightTabsByLeftGrid.TryGetValue(leftGrid, out XtraTabControl rightTab)) + { + RefreshRightTab(rightTab, leftGrid); + } + } + /// /// 新模式加载明细控件 /// @@ -481,6 +556,7 @@ namespace Lskj.Control System.Windows.Forms.Control childCtrl = CreateDetailControl(childPage, child, dataCaches, true, leftControl); childPage.Controls.Add(childCtrl); rightTab.TabPages.Add(childPage); + _rightSideTabPages.Add(childPage); } split.Panel2.Controls.Add(rightTab); @@ -488,18 +564,15 @@ namespace Lskj.Control // 如果它是网格,就把事件绑上去 if (leftCtrl is GridControlEx g1) { - g1.GridView.FocusedRowObjectChanged += (s, e) => RefreshRightTab(rightTab, g1); - RefreshRightTab(rightTab, g1);// 首次加载 + RegisterRightTabRefresh(g1, rightTab); } else if (leftCtrl is ModuleGridEx mg) { var g2 = mg.GridControlObj; - g2.GridView.FocusedRowObjectChanged += (s, e) => RefreshRightTab(rightTab, g2); - RefreshRightTab(rightTab, g2); // 首次加载 + RegisterRightTabRefresh(g2, rightTab); } else if (page.Tag is GridControlEx g3) { - g3.GridView.FocusedRowObjectChanged += (s, e) => RefreshRightTab(rightTab, g3); - RefreshRightTab(rightTab, g3);// 首次加载 + RegisterRightTabRefresh(g3, rightTab); } page.Controls.Add(split);// 跟原来保持一致的 Tag 用法 } @@ -1388,6 +1461,10 @@ namespace Lskj.Control if (model.HideBottomPanel|| model.Library.Equals("Lskj.Report.dll", StringComparison.OrdinalIgnoreCase)) { gridEx.VisibleOperPanel = false; + dyncModel = new DynamicReportModel(new[] + { model.DetailName, ERPInfo.Instance.UserId, ERPInfo.Instance.UserName, + this.Model.Privilege, model.UnionModule, "0" }); + } gridEx.InitializeControl(model.SystemModel, dyncModel); @@ -2151,6 +2228,12 @@ namespace Lskj.Control gridControl.SetGridViewDataSource(table); dataRowCount = gridControl.GridView.DataRowCount; } + //数据源为空时,主动触发右侧刷新 + if (dataRowCount == 0) + { + RefreshRightTabAfterLeftBind(gridControl); + } + if (IsDragDetail && this.ParentGridEx != null && model.IsDrag) { gridControl.GridView.DoubleClick += new EventHandler(OnGridCompleted); @@ -2170,6 +2253,7 @@ namespace Lskj.Control } //tabPage.Text = gridControl.CustomGroupBandEx != null ? model.DetailName + "(" + gridControl.CustomGroupBandEx.DataRowCount() + "条)" : model.DetailName + "(" + dataRowCount + ")"; tabPage.Appearance.Header.ForeColor = dataRowCount > 0 ? Color.Red : Color.FromArgb(0, 0, 0); + } @@ -2721,4 +2805,4 @@ namespace Lskj.Control if (childTreeBandView != null) { // 调整底部bandGcBottom的列宽(始终为BandedGridView类型) - List bottomColumnList = new List bottomColumnList = new List修改备注: /// 版本:1.0 /// - /// 判断是否只刷新UpdateColumn中配置的列的数据源 - public void RefreshDataSource(bool UpdateColumnRefresh = false) - { - //this.mLoading = false; - SetColumnsSource(); - } - - - /// - /// 设置序号列宽度 - /// - public void AdjustIndicatorWidthSmart() - { - try - { - int nodeCount = this.TreeListObj.AllNodesCount;// 获取节点总数 - if (nodeCount == 0) return; - // 计算数字宽度(TreeList可能有层级,适当增加系数) - int numberWidth = (int)(nodeCount.ToString().Length * 7.5) + 16; // 系数和偏移量略大于GridView - - // 设置宽度(范围可适当放宽,如50-100px,适应层级缩进) - this.TreeListObj.IndicatorWidth = Math.Max(40, Math.Min(80, numberWidth)); - } - catch (Exception ex) - { - - } - } - - - - - - } -} + /// 判断是否只刷新UpdateColumn \ No newline at end of file