diff --git a/插件库/Lskj.Business/Impl/SystemInfo.cs b/插件库/Lskj.Business/Impl/SystemInfo.cs
index b8296d6..68196be 100644
--- a/插件库/Lskj.Business/Impl/SystemInfo.cs
+++ b/插件库/Lskj.Business/Impl/SystemInfo.cs
@@ -342,12 +342,17 @@ namespace Lskj.Business
Instance.IsSpecialAuditSave = item.Table.Columns.Contains("IsSpecialAuditSave") && !string.IsNullOrEmpty(item["IsSpecialAuditSave"] + "") ? "1".Equals(item["IsSpecialAuditSave"] + "") : false;
Instance.SuppressImportSuccessTip = item.Table.Columns.Contains("SuppressImportSuccessTip") && !string.IsNullOrEmpty(item["SuppressImportSuccessTip"] + "") ? "1".Equals(item["SuppressImportSuccessTip"] + "") : false;
- string newMainValue = item.Table.Columns.Contains("NewMain") ? (item["NewMain"] + "").Trim() : "";
- Instance.NewMain = "1".Equals(newMainValue) || "true".Equals(newMainValue, StringComparison.OrdinalIgnoreCase);
+ Instance.NewMain = item.Table.Columns.Contains("NewMain") && !string.IsNullOrEmpty(item["NewMain"] + "") ? "1".Equals(item["NewMain"] + "") : false;
if (Instance.NewMain)
{
Instance.MainLeftShowMode = "1";
Instance.DefaultMainTag = 4;
+ Instance.MainTopColor = item.Table.Columns.Contains("MainTopColor") && !string.IsNullOrEmpty(item["MainTopColor"] + "") ? item["MainTopColor"] + "" : "";
+ Instance.MainLeftSelectColor = item.Table.Columns.Contains("MainLeftSelectColor") && !string.IsNullOrEmpty(item["MainLeftSelectColor"] + "") ? item["MainLeftSelectColor"] + "" : "";
+ Instance.MainLeftColor = item.Table.Columns.Contains("MainLeftColor") && !string.IsNullOrEmpty(item["MainLeftColor"] + "") ? item["MainLeftColor"] + "" : "";
+ Instance.MainTopFontSize = item.Table.Columns.Contains("MainTopFontSize") && !string.IsNullOrEmpty(item["MainTopFontSize"] + "") ? Convert.ToInt32(item["MainTopFontSize"] + "") : 0;
+ Instance.MainLeftFontSize = item.Table.Columns.Contains("MainLeftFontSize") && !string.IsNullOrEmpty(item["MainLeftFontSize"] + "") ? Convert.ToInt32(item["MainLeftFontSize"] + "") : 0;
+
}
}
///
@@ -1203,13 +1208,17 @@ namespace Lskj.Business
///
public string MainLeftColor;
///
+ /// 新版界面左侧选中背景色
+ ///
+ public string MainLeftSelectColor;
+ ///
/// 新版界面顶部字体大小
///
- public string MainTopFontSize;
+ public int MainTopFontSize;
///
/// 新版界面左侧字体大小
///
- public string MainLeftFontSize;
+ public int MainLeftFontSize;
}
}
diff --git a/插件库/Lskj.Control/BandedGridControlEx.cs b/插件库/Lskj.Control/BandedGridControlEx.cs
index 13fc52c..ab9cb05 100644
--- a/插件库/Lskj.Control/BandedGridControlEx.cs
+++ b/插件库/Lskj.Control/BandedGridControlEx.cs
@@ -122,6 +122,8 @@ namespace Lskj.Control
this.bandedGridView.PopupMenuShowing += new DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventHandler(this.OnGridViewPopupMenuShowing);
this.bandedGridView.Click += new EventHandler(OnBandedGridView_Click);
this.bandedGridView.DoubleClick += new EventHandler(OnBandedGridViewDoubleClick);
+ // 多表头的操作列使用 BandedGridView,复用基类的禁编按钮点击处理。
+ this.bandedGridView.MouseDown += GridView_MouseDown;
this.bandedGridView.CustomDrawGroupRow += new RowObjectCustomDrawEventHandler(OnGridCustomDrawGroupRow);
this.bandedGridView.LeftCoordChanged += OnBandedLeftCoordChanged;
this.SetGridRowHeightAndFont();
@@ -133,6 +135,236 @@ namespace Lskj.Control
this.bandedGridView.ShowingEditor += GridView_ShowingEditor;
}
+ ///
+ /// 多表头创建或重建操作列。
+ /// 操作列不参与业务列配置,只挂到空白一级表头的最右侧。
+ ///
+ protected override void TryInitRightMenuBtnEdit(bool rebuild)
+ {
+ if (!this.gridColumnsInitialized || this.Model == null ||
+ (this.CustomColumKey ?? string.Empty).Contains("BaseLeftGridView_"))
+ {
+ return;
+ }
+
+ BandedGridColumn oldColumn = this.bandedGridView.Columns["RightMenuBtnEdit"];
+ bool showButtonColumn = this.rightMenuButtonTable != null &&
+ this.rightMenuButtonTable.Rows.Cast().Any(row =>
+ (row.Table.Columns.Contains("IcoName") &&
+ !string.IsNullOrWhiteSpace(row["IcoName"] + "")) ||
+ (row.Table.Columns.Contains("showtoolbar") &&
+ "1".Equals(row["showtoolbar"] + "")));
+ if (!showButtonColumn)
+ {
+ if (oldColumn != null)
+ {
+ this.RemoveRightMenuButtonColumn(oldColumn);
+ }
+ return;
+ }
+
+ if (oldColumn != null)
+ {
+ if (!rebuild)
+ {
+ return;
+ }
+ this.RemoveRightMenuButtonColumn(oldColumn);
+ }
+
+ this.InitRightMenuBtnEdit(this.rightMenuButtonTable);
+ DataTable dataSource = this.GridControl == null ? null : this.GridControl.DataSource as DataTable;
+ if (dataSource != null && !dataSource.Columns.Contains("RightMenuBtnEdit"))
+ {
+ dataSource.Columns.Add("RightMenuBtnEdit");
+ }
+ }
+
+ ///
+ /// 删除旧操作列,同时保持空白一级表头下其他列的现有宽度。
+ ///
+ private void RemoveRightMenuButtonColumn(BandedGridColumn oldColumn)
+ {
+ GridBand ownerBand = oldColumn.OwnerBand;
+ int oldColumnWidth = oldColumn.Width;
+ int originalBandWidth = ownerBand == null ? 0 : ownerBand.Width;
+ Dictionary originalColumnWidths = ownerBand == null
+ ? new Dictionary()
+ : ownerBand.Columns.Cast()
+ .Where(column => column != oldColumn)
+ .ToDictionary(column => column, column => column.Width);
+
+ this.bandedGridView.BeginUpdate();
+ try
+ {
+ this.bandedGridView.Columns.Remove(oldColumn);
+ if (ownerBand == null)
+ {
+ return;
+ }
+
+ if (ownerBand.Columns.Count == 0)
+ {
+ this.bandedGridView.Bands.Remove(ownerBand);
+ }
+ else
+ {
+ ownerBand.Width = Math.Max(0, originalBandWidth - oldColumnWidth);
+ foreach (KeyValuePair item in originalColumnWidths)
+ {
+ item.Key.Width = item.Value;
+ }
+ }
+ }
+ finally
+ {
+ this.bandedGridView.EndUpdate();
+ }
+ }
+
+ ///
+ /// 创建多表头操作列,并将其放到空白一级表头的最右侧。
+ ///
+ protected override void InitRightMenuBtnEdit(DataTable rightMenuTab)
+ {
+ if (rightMenuTab == null)
+ {
+ return;
+ }
+
+ BandedGridColumn gridColumn = new BandedGridColumn();
+ gridColumn.FieldName = "RightMenuBtnEdit";
+ gridColumn.Name = "RightMenuBtnEdit";
+ gridColumn.Caption = "操作列";
+ gridColumn.Visible = true;
+ gridColumn.OptionsColumn.AllowEdit = true;
+
+ RepositoryItemButtonEdit itemButtonEdit = new RepositoryItemButtonEdit();
+ itemButtonEdit.Buttons.Clear();
+ itemButtonEdit.AppearanceDisabled.Options.UseTextOptions = true;
+ itemButtonEdit.AppearanceDisabled.TextOptions.HAlignment = HorzAlignment.Center;
+ itemButtonEdit.TextEditStyle = TextEditStyles.HideTextEditor;
+ itemButtonEdit.ButtonsStyle = BorderStyles.UltraFlat;
+ itemButtonEdit.BorderStyle = BorderStyles.NoBorder;
+ itemButtonEdit.ButtonClick += new ButtonPressedEventHandler(OnItemButtonEdit_ButtonClick);
+
+ int columnWidth = 0;
+ if (rightMenuTab.Columns.Contains("IcoName"))
+ {
+ DataRow[] rightMenuButtons = rightMenuTab.Select()
+ .Where(n => !string.IsNullOrEmpty(n["IcoName"] + ""))
+ .ToArray();
+ int pictureWidth = 30;
+ foreach (DataRow rightMenu in rightMenuButtons)
+ {
+ GridRightMenuModel menuModel = new GridRightMenuModel(rightMenu);
+ if (string.IsNullOrWhiteSpace(menuModel.MenuName))
+ {
+ continue;
+ }
+
+ EditorButton editorButton = new EditorButton();
+ editorButton.Appearance.BackColor = Color.Transparent;
+ if (!string.IsNullOrEmpty(menuModel.IcoName))
+ {
+ try
+ {
+ Image image = GetRightMenuButtonImage(menuModel.IcoName);
+ if (image != null && image.Width > 30)
+ {
+ pictureWidth = image.Width;
+ }
+ editorButton.Image = image;
+ }
+ catch (Exception)
+ {
+ }
+ }
+ editorButton.ToolTip = menuModel.MenuName;
+ editorButton.Kind = ButtonPredefines.Glyph;
+ editorButton.Width = pictureWidth;
+ editorButton.Tag = menuModel;
+ itemButtonEdit.Buttons.Add(editorButton);
+ }
+ columnWidth = rightMenuButtons.Length * pictureWidth;
+ }
+
+ if (rightMenuTab.Columns.Contains("showtoolbar"))
+ {
+ DataRow[] rightMenuTextButtons = rightMenuTab.Select()
+ .Where(n => "1".Equals(n["showtoolbar"] + ""))
+ .ToArray();
+ foreach (DataRow rightMenu in rightMenuTextButtons)
+ {
+ GridRightMenuModel menuModel = new GridRightMenuModel(rightMenu);
+ if (string.IsNullOrWhiteSpace(menuModel.MenuName))
+ {
+ continue;
+ }
+
+ EditorButton editorButton = new EditorButton();
+ editorButton.Caption = menuModel.MenuName + "";
+ editorButton.ToolTip = menuModel.MenuName;
+ editorButton.Kind = ButtonPredefines.Glyph;
+ editorButton.Width = this.CalculateTextWidth(editorButton.Caption, editorButton.Appearance.Font);
+ editorButton.Tag = menuModel;
+ editorButton.Appearance.BackColor = Color.FromArgb(240, 240, 240);
+ editorButton.Appearance.BorderColor = Color.FromArgb(180, 180, 180);
+ editorButton.Appearance.ForeColor = Color.FromArgb(50, 50, 50);
+ editorButton.Appearance.Options.UseBackColor = true;
+ editorButton.Appearance.Options.UseBorderColor = true;
+ editorButton.Appearance.Options.UseForeColor = true;
+ itemButtonEdit.Buttons.Add(editorButton);
+ columnWidth += editorButton.Width;
+ }
+ }
+
+ gridColumn.ColumnEdit = itemButtonEdit;
+ gridColumn.MaxWidth = columnWidth;
+ gridColumn.MinWidth = columnWidth;
+ gridColumn.Width = columnWidth;
+
+ GridBand emptyBand = this.bandedGridView.Bands.Cast()
+ .FirstOrDefault(x => string.IsNullOrEmpty(x.Caption));
+ if (emptyBand == null)
+ {
+ emptyBand = new GridBand();
+ emptyBand.Caption = "";
+ emptyBand.AppearanceHeader.Options.UseFont = true;
+ emptyBand.AppearanceHeader.Font = new Font("宋体", 9, FontStyle.Bold);
+ emptyBand.AppearanceHeader.Options.UseTextOptions = true;
+ emptyBand.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
+ this.bandedGridView.Bands.Add(emptyBand);
+ }
+
+ int originalBandWidth = emptyBand.Width;
+ Dictionary originalColumnWidths = emptyBand.Columns
+ .Cast()
+ .ToDictionary(column => column, column => column.Width);
+
+ this.bandedGridView.BeginUpdate();
+ try
+ {
+ emptyBand.Columns.Add(gridColumn);
+ this.bandedGridView.Columns.Add(gridColumn);
+ gridColumn.ColVIndex = emptyBand.Columns.Count - 1;
+
+ // DevExpress 默认保持 Band 总宽度,新增列时会压缩同一 Band 下的原列。
+ // 恢复原列宽,并单独为操作列扩展一级表头宽度。
+ emptyBand.Width = originalBandWidth + columnWidth;
+ foreach (KeyValuePair item in originalColumnWidths)
+ {
+ item.Key.Width = item.Value;
+ }
+ gridColumn.Width = columnWidth;
+ }
+ finally
+ {
+ this.bandedGridView.EndUpdate();
+ }
+ this.bandedGridView.OptionsBehavior.EditorShowMode = EditorShowMode.MouseDown;
+ }
+
///
@@ -574,6 +806,7 @@ namespace Lskj.Control
protected void AddBandColumns(DataTable table, bool readOnly = true)
{
if (table == null) return;
+ this.gridColumnsInitialized = false;
this.InitGridColumsTab = table;
this.mControlList.Clear();
List bandFieldstr = new List();
@@ -844,6 +1077,8 @@ namespace Lskj.Control
// 加载数据源
//BindDataSource();
this.SetCustomColumns();//加载多表头自定义列
+ this.gridColumnsInitialized = true;
+ this.TryInitRightMenuBtnEdit(false);
//多表头冻结
foreach (BandedGridColumn item in FrozenColumns)
diff --git a/插件库/Lskj.Control/FrmExport.cs b/插件库/Lskj.Control/FrmExport.cs
index fae2a18..0912fd3 100644
--- a/插件库/Lskj.Control/FrmExport.cs
+++ b/插件库/Lskj.Control/FrmExport.cs
@@ -178,6 +178,12 @@ namespace Lskj.Control
foreach (GridColumn col in gridView.Columns)
{
+ if (col.FieldName.Equals("RightMenuBtnEdit", StringComparison.OrdinalIgnoreCase))
+ {
+ // 操作列仅用于界面按钮,不应进入导出结果。
+ hasBoolean = true;
+ continue;
+ }
if ((col.ColumnEdit != null && col.ColumnEdit.GetType() == typeof(RepositoryItemCheckEdit)) ||
(col.ColumnType != null && col.ColumnType.Name.ToLower() == "boolean"))
{
@@ -209,7 +215,7 @@ namespace Lskj.Control
foreach (BandedGridColumn col in gridView.Columns)
{
GridColumnModel gridModel = col.Tag as GridColumnModel;
- if (col.Visible)
+ if (col.Visible && !col.FieldName.Equals("RightMenuBtnEdit", StringComparison.OrdinalIgnoreCase))
{
BandedGridColumn newCol = new BandedGridColumn();
newCol.Tag = col.Tag;
diff --git a/插件库/Lskj.Control/GridControlEx.cs b/插件库/Lskj.Control/GridControlEx.cs
index 9523c9c..e4cecce 100644
--- a/插件库/Lskj.Control/GridControlEx.cs
+++ b/插件库/Lskj.Control/GridControlEx.cs
@@ -184,8 +184,8 @@ namespace Lskj.Control
///
/// 外部设置的右键菜单数据,用于创建每行操作列。
///
- private DataTable rightMenuButtonTable;
- private bool gridColumnsInitialized;
+ protected DataTable rightMenuButtonTable;
+ protected bool gridColumnsInitialized;
///
/// 新版模块选择框缓存。同一关联模块的单选和多选界面分别复用。
@@ -5649,8 +5649,8 @@ namespace Lskj.Control
///
internal void SetRightMenuButtonTable(DataTable table)
{
- // 树表格和多表头表格原来不在此处创建操作列,维持原有行为。
- if (this is TreeGridControlEx || this is BandedGridControlEx)
+ // 树表格仍由原有逻辑处理,不创建操作列。
+ if (this is TreeGridControlEx)
{
return;
}
@@ -5659,7 +5659,7 @@ namespace Lskj.Control
this.TryInitRightMenuBtnEdit(true);
}
- private void TryInitRightMenuBtnEdit(bool rebuild)
+ protected virtual void TryInitRightMenuBtnEdit(bool rebuild)
{
if (!this.gridColumnsInitialized || this.Model == null ||
this.CustomColumKey.Contains("BaseLeftGridView_"))
@@ -5689,7 +5689,7 @@ namespace Lskj.Control
}
}
- private void InitRightMenuBtnEdit(DataTable rightMenuTab)
+ protected virtual void InitRightMenuBtnEdit(DataTable rightMenuTab)
{
GridColumn gridColumn = new GridColumn();
gridColumn.FieldName = "RightMenuBtnEdit";
@@ -9771,7 +9771,7 @@ namespace Lskj.Control
///
///
///
- private void OnItemButtonEdit_ButtonClick(object sender, ButtonPressedEventArgs e)
+ protected void OnItemButtonEdit_ButtonClick(object sender, ButtonPressedEventArgs e)
{
EditorButton editorButton = e.Button as EditorButton;
GridRightMenuModel menuModel = editorButton.Tag as GridRightMenuModel;
@@ -9779,8 +9779,8 @@ namespace Lskj.Control
if (toolStripMenuItem != null)
{
bool allowClick = true;
- int[] mSelectRows = this.gridView.GetSelectedRows();
- DataRow mSelectRow = this.gridView.GetDataRow(mSelectRows[0]);
+ int[] mSelectRows = this.GridView.GetSelectedRows();
+ DataRow mSelectRow = this.GridView.GetDataRow(mSelectRows[0]);
if (menuModel != null)
{
if (menuModel.PrivilegeOper.Length > 1 && !menuModel.PrivilegeOper.Contains(ERPInfo.Instance.UserName + ","))
@@ -9797,13 +9797,13 @@ namespace Lskj.Control
if (this.gridViewRightMenu.ControlObj != null)
cond = this.gridViewRightMenu.ControlObj.ReplaceParentControlValue(menuModel.MenuCond);
cond = ReplaceHelper.ReplaceRowParam(mSelectRow, menuModel.MenuCond);
- if (this.gridView != null)
+ if (this.GridView != null)
{
- GridCell[] cells = this.gridView.GetSelectedCells();
+ GridCell[] cells = this.GridView.GetSelectedCells();
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
{
GridCell cell = cells[0];
- DataRow focusedRow = this.gridView.GetFocusedDataRow();
+ DataRow focusedRow = this.GridView.GetFocusedDataRow();
string colValue = focusedRow == null || !focusedRow.Table.Columns.Contains(cell.Column.Name) ? "" : focusedRow[cell.Column.Name] + "";
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
}
@@ -11113,7 +11113,7 @@ namespace Lskj.Control
return Math.Max(textWidth + padding, 40);
}
- private Image GetRightMenuButtonImage(string imageName)
+ protected Image GetRightMenuButtonImage(string imageName)
{
if (string.IsNullOrWhiteSpace(imageName))
{
@@ -11177,7 +11177,7 @@ namespace Lskj.Control
///
///
///
- private void GridView_MouseDown(object sender, MouseEventArgs e)
+ protected void GridView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
@@ -11190,7 +11190,7 @@ namespace Lskj.Control
RepositoryItemButtonEdit repo = hitInfo.Column.ColumnEdit as RepositoryItemButtonEdit;
if (!hitInfo.Column.FieldName.Equals("RightMenuBtnEdit")) return;
int rowHandle = hitInfo.RowHandle;
- this.gridView.SelectRowHandler(rowHandle);
+ view.SelectRowHandler(rowHandle);
int buttonIndex = this.GetClickedButtonIndex(repo, view, rowHandle, hitInfo.Column, e.Location, hitInfo.Column.Width);
if (buttonIndex != -1)
@@ -11207,7 +11207,7 @@ namespace Lskj.Control
/// 执行点击的右键按钮
///
///
- private void RightButtonClick(EditorButton editorButton)
+ protected void RightButtonClick(EditorButton editorButton)
{
GridRightMenuModel menuModel = editorButton.Tag as GridRightMenuModel;
@@ -11215,8 +11215,8 @@ namespace Lskj.Control
if (toolStripMenuItem != null)
{
bool allowClick = true;
- int[] mSelectRows = this.gridView.GetSelectedRows();
- DataRow mSelectRow = this.gridView.GetDataRow(mSelectRows[0]);
+ int[] mSelectRows = this.GridView.GetSelectedRows();
+ DataRow mSelectRow = this.GridView.GetDataRow(mSelectRows[0]);
if (menuModel != null)
{
if (menuModel.PrivilegeOper.Length > 1 && !menuModel.PrivilegeOper.Contains(ERPInfo.Instance.UserName + ","))
@@ -11233,13 +11233,13 @@ namespace Lskj.Control
if (this.gridViewRightMenu.ControlObj != null)
cond = this.gridViewRightMenu.ControlObj.ReplaceParentControlValue(menuModel.MenuCond);
cond = ReplaceHelper.ReplaceRowParam(mSelectRow, menuModel.MenuCond);
- if (this.gridView != null)
+ if (this.GridView != null)
{
- GridCell[] cells = this.gridView.GetSelectedCells();
+ GridCell[] cells = this.GridView.GetSelectedCells();
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
{
GridCell cell = cells[0];
- DataRow focusedRow = this.gridView.GetFocusedDataRow();
+ DataRow focusedRow = this.GridView.GetFocusedDataRow();
string colValue = focusedRow == null || !focusedRow.Table.Columns.Contains(cell.Column.Name) ? "" : focusedRow[cell.Column.Name] + "";
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
}
diff --git a/插件库/Lskj.Control/Model/GridExtend.cs b/插件库/Lskj.Control/Model/GridExtend.cs
index a7031ee..d64415b 100644
--- a/插件库/Lskj.Control/Model/GridExtend.cs
+++ b/插件库/Lskj.Control/Model/GridExtend.cs
@@ -622,6 +622,8 @@ namespace Lskj.Control.Model
}
GridColumnModel model = col.Tag as GridColumnModel;
+ // 操作列是运行时创建的界面列,不参与个性化保存。
+ if (model == null) continue;
DataRow a = customTable.Rows.Cast().FirstOrDefault(x => col.Name.Equals(x["fieldName"] + "", StringComparison.OrdinalIgnoreCase));
string tempSql = a == null ? string.Format(@"insert into {8}(formkey,fieldname,username,orderid,isvisible,operatorid,operatorName,operatedate,fieldWidth,IfFixColumn,FieldText {11}) values('{0}','{1}','{2}','{3}','{4}','{5}','{6}',getdate(),'{7}','{9}','{10}' {12});",
key, col.FieldName, col.Caption, col.VisibleIndex, Convert.ToInt32(col.Visible), ERPInfo.Instance.UserId, ERPInfo.Instance.UserName, col.Width, ResourceKeys.SettingTableName, col.OwnerBand != null ? col.OwnerBand.Fixed == DevExpress.XtraGrid.Columns.FixedStyle.Left ? 1 : 0 : 0, model.FieldText, saveFieldName, fieldValue) : string.Format(@"update {6} set orderid='{0}',fieldWidth='{1}',isvisible={2},IfFixColumn='{7}' {8} where formkey='{3}' and fieldname='{4}' and operatorid='{5}';",
@@ -1146,6 +1148,8 @@ namespace Lskj.Control.Model
gridControl.gridViewRightMenu = rightMenu;
rightMenu.InitRightMenus(gridControl, table, model, control, menu);
rightMenu.SetRightCallback(handler);
+ // 右键菜单创建完成后再生成多表头操作列,确保按钮数据完整。
+ gridControl.SetRightMenuButtonTable(table);
}
///
/// 说明:设置图标右键菜单
diff --git a/插件库/Lskj.Control/ModuleGridDetailEx.cs b/插件库/Lskj.Control/ModuleGridDetailEx.cs
index bf78a5a..3b2e6ad 100644
--- a/插件库/Lskj.Control/ModuleGridDetailEx.cs
+++ b/插件库/Lskj.Control/ModuleGridDetailEx.cs
@@ -358,6 +358,11 @@ namespace Lskj.Control
tcButtom.OnDetailRightCallback += OnGridViewRightCallBack;
}
+ if (this.SysModel.RefreshTheInterface)
+ {
+
+ }
+
this.tcButtom.Model = this.Model;
this.tcButtom.DrgaParentPrimaryKey = this.SysModel.ParmaryKey;
this.tcButtom.IsDragDetail = this.IsDragDetail;
@@ -387,6 +392,11 @@ namespace Lskj.Control
tcButtom.OnDetailRightCallback += OnGridViewRightCallBack;
}
+ if (this.SysModel.RefreshTheInterface)
+ {
+
+ }
+
this.tcButtom.Model = this.Model;
this.tcButtom.DrgaParentPrimaryKey = this.SysModel.ParmaryKey;
this.tcButtom.IsDragDetail = this.IsDragDetail;
diff --git a/插件库/Lskj.Control/TabControlEx.cs b/插件库/Lskj.Control/TabControlEx.cs
index 8a8cdb4..e1fd8c1 100644
--- a/插件库/Lskj.Control/TabControlEx.cs
+++ b/插件库/Lskj.Control/TabControlEx.cs
@@ -142,6 +142,13 @@ namespace Lskj.Control
///
public event EventHandler BillDetailRightGridCallBack;
+ ///
+ /// 新版左右结构下,左侧或者右侧的表格数据改变后,刷新主表数据(主表刷新后会刷新当前明细或者全部明细)
+ ///
+ /// The sender.
+ public event EventHandler OnDataChangeExecution;
+
+
///
/// 明细页签与主模块对应关系
///
@@ -181,6 +188,9 @@ namespace Lskj.Control
/// 页签名(判断是否有重复的左右结构)
///
public string DetaiName = string.Empty;
+
+
+
public TabControlEx()
{
InitializeComponent();
diff --git a/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs b/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs
index 4d5ca08..acb23ba 100644
--- a/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs
+++ b/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs
@@ -5,6 +5,7 @@ using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
+using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -12,6 +13,7 @@ using System.Windows.Forms;
using DevExpress.XtraTab;
using DevExpress.XtraTreeList;
using Lskj.Business;
+using Lskj.Main;
using Lskj.Model;
using WinFormsControl = System.Windows.Forms.Control;
@@ -26,10 +28,15 @@ namespace Lskj.Main.Control
private static readonly Color ShortcutBorderColor = Color.FromArgb(221, 227, 234);
private System.ComponentModel.IContainer components = null;
private MainPanelControlEx _legacyPanel;
+ private MainTabsNativeWindow _mainTabsNativeWindow;
protected override void Dispose(bool disposing)
{
- if (disposing && (components != null)) components.Dispose();
+ if (disposing)
+ {
+ if (_mainTabsNativeWindow != null) _mainTabsNativeWindow.Dispose();
+ if (components != null) components.Dispose();
+ }
base.Dispose(disposing);
}
@@ -62,35 +69,37 @@ namespace Lskj.Main.Control
#region 新版主界面外观
private void ApplyWpfShellStyle()
{
+ MainAppearanceSettings appearance = MainAppearanceSettingsStore.Load();
+ Color headerColor = GetConfiguredColor(appearance.TopMenuBackground, HeaderColor);
Panel header = FindControl("plTop");
Panel headerLeft = FindControl("pl_top_left");
Panel headerCenter = FindControl("pl_top_center");
Panel headerRight = FindControl("pl_top_right");
Panel headerSeparator = FindControl("panel3");
MenuStrip topMenu = FindControl("menuMain");
- if (header != null) { header.Height = 50; header.BackColor = HeaderColor; }
+ if (header != null) { header.Height = 50; header.BackColor = headerColor; }
if (headerLeft != null)
{
headerLeft.Width = 176;
- headerLeft.BackColor = HeaderColor;
+ headerLeft.BackColor = headerColor;
headerLeft.BackgroundImage = null;
AddBrandVisual(headerLeft);
}
- if (headerCenter != null) { headerCenter.BackColor = HeaderColor; headerCenter.Padding = new Padding(0, 9, 0, 0); }
+ if (headerCenter != null) { headerCenter.BackColor = headerColor; headerCenter.Padding = new Padding(0, 9, 0, 0); }
// 右上角继续使用旧版控件、按钮和位置,仅统一顶部背景色。
- if (headerRight != null) { headerRight.BackColor = HeaderColor; headerRight.BackgroundImage = null; }
+ if (headerRight != null) { headerRight.BackColor = headerColor; headerRight.BackgroundImage = null; }
// 旧版 Logo 与菜单之间有 19px 的装饰分隔面板;WPF 顶部栏是连续布局,
// 保留该控件会在两块蓝色之间形成突兀的深色竖条。
if (headerSeparator != null)
{
headerSeparator.Width = 0;
- headerSeparator.BackColor = HeaderColor;
+ headerSeparator.BackColor = headerColor;
headerSeparator.BackgroundImage = null;
}
StyleSearchControls();
- if (topMenu != null) StyleTopNavigation(topMenu);
+ if (topMenu != null) StyleTopNavigation(topMenu, headerColor, appearance.TopMenuFontSize);
StyleMainTabs();
- StyleSidebar();
+ StyleSidebar(appearance);
StyleWorkspaceAndShortcuts();
RememberStyledNavigation();
}
@@ -147,8 +156,13 @@ namespace Lskj.Main.Control
Color tabHover = Color.White;
Color tabBorder = Color.FromArgb(199, 211, 228);
tabs.PaintStyleName = "Flat";
+ tabs.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
+ tabs.BorderStylePage = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
tabs.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Top;
tabs.HeaderAutoFill = DevExpress.Utils.DefaultBoolean.False;
+ tabs.MultiLine = DevExpress.Utils.DefaultBoolean.False;
+ tabs.ShowHeaderFocus = DevExpress.Utils.DefaultBoolean.False;
+ tabs.MaxTabPageWidth = 220;
tabs.TabPageWidth = 0;
tabs.BackColor = tabStrip;
tabs.Appearance.BackColor = tabStrip;
@@ -162,18 +176,69 @@ namespace Lskj.Main.Control
tabs.AppearancePage.HeaderHotTracked.Font = tabs.AppearancePage.Header.Font;
tabs.AppearancePage.HeaderDisabled.Font = tabs.AppearancePage.Header.Font;
tabs.Paint -= MainTabs_Paint;
- tabs.Paint += MainTabs_Paint;
+ if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
+ tabs.Paint += MainTabs_Paint;
+ else
+ AttachMainTabsNativePainter(tabs);
+ tabs.ControlAdded -= MainTabs_ControlAdded;
+ tabs.ControlAdded += MainTabs_ControlAdded;
- // 功能导航页签要与左侧 176px 目录栏严格对齐。DevExpress 旧版
- // 页签宽度按文本自适应,因此用不可见的全角空格补足首个页签宽度,
- // 其它页签仍保持按内容自适应,并通过边框清晰分隔。
+ // WPF 首页页签固定 176px,其余页签为 92~220px。直接使用每页的
+ // TabPageWidth,避免用全角空格补宽后在不同字体/DPI 下发生偏移。
XtraTabPage first = tabs.TabPages.Cast().FirstOrDefault(p => p.Name == "xtpFirst");
- if (first != null) first.Text = "功能导航" + new string('\u3000', 10);
+ if (first != null) first.Text = "功能导航";
+ ApplyWpfTabWidths(tabs);
+ }
+
+ private void MainTabs_ControlAdded(object sender, ControlEventArgs e)
+ {
+ XtraTabControl tabs = sender as XtraTabControl;
+ if (tabs == null || !(e.Control is XtraTabPage)) return;
+ ApplyWpfTabWidths(tabs);
+ tabs.Invalidate();
+ }
+
+ private void AttachMainTabsNativePainter(XtraTabControl tabs)
+ {
+ if (_mainTabsNativeWindow == null)
+ _mainTabsNativeWindow = new MainTabsNativeWindow();
+ _mainTabsNativeWindow.Attach(tabs);
+ }
+
+ private static void ApplyWpfTabWidths(XtraTabControl tabs)
+ {
+ Font font = tabs.AppearancePage.Header.Font ?? tabs.Font;
+ foreach (XtraTabPage page in tabs.TabPages)
+ {
+ if (page.Name == "xtpFirst")
+ {
+ page.TabPageWidth = 167;
+ continue;
+ }
+ if (page.Name == "xtpWorktop" || page.Name == "xtpDesktop")
+ {
+ page.TabPageWidth = 83;
+ continue;
+ }
+
+ int textWidth = TextRenderer.MeasureText(page.Text ?? string.Empty, font,
+ Size.Empty, TextFormatFlags.NoPadding | TextFormatFlags.SingleLine).Width;
+ // WPF:左右文字留白 20px,关闭按钮及间隔 20px。
+ // DevExpress 15.2 会在 TabPageWidth 外再增加 9px 头部外框;
+ // 预先扣除该值,使最终可见宽度与 WPF 的 92~220px 一致。
+ int visualWidth = Math.Max(92, Math.Min(220, textWidth + 40));
+ page.TabPageWidth = Math.Max(1, visualWidth - 9);
+ }
}
private void MainTabs_Paint(object sender, PaintEventArgs e)
{
XtraTabControl tabs = sender as XtraTabControl;
+ if (tabs != null) DrawMainTabs(tabs, e.Graphics);
+ }
+
+ private static void DrawMainTabs(XtraTabControl tabs, Graphics graphics)
+ {
DevExpress.XtraTab.IXtraTab tabInterface = tabs as DevExpress.XtraTab.IXtraTab;
DevExpress.XtraTab.ViewInfo.BaseTabControlViewInfo viewInfo =
tabInterface == null ? null : tabInterface.ViewInfo;
@@ -181,47 +246,85 @@ namespace Lskj.Main.Control
Rectangle header = viewInfo.HeaderInfo.Bounds;
if (header.Width <= 0 || header.Height <= 0) return;
- Color stripColor = Color.FromArgb(243, 245, 248);
- Color borderColor = Color.FromArgb(199, 211, 228);
- int lastRight = header.Left;
+ Color stripColor = Color.FromArgb(243, 245, 248); // #F3F5F8
+ Color normalColor = Color.FromArgb(248, 250, 252); // #F8FAFC
+ Color normalBorder = Color.FromArgb(199, 211, 228); // #C7D3E4
+ Color selectedBorder = Color.FromArgb(199, 211, 228); // #C7D3E4
+ Color normalText = Color.FromArgb(79, 95, 120); // #4F5F78
+ Color selectedText = Color.FromArgb(7, 88, 255); // #0758FF
+ int dividerY = viewInfo.PageClientBounds.Top > 0
+ ? viewInfo.PageClientBounds.Top - 1
+ : header.Bottom - 1;
+ dividerY = Math.Max(header.Top, Math.Min(tabs.ClientSize.Height - 1, dividerY));
+
+ // 先覆盖整个页签带,彻底消除 DevExpress 当前皮肤留下的渐变、圆角和焦点边框。
+ using (Brush stripBrush = new SolidBrush(stripColor))
+ graphics.FillRectangle(stripBrush, 0, header.Top,
+ tabs.ClientSize.Width, Math.Max(1, dividerY - header.Top + 1));
foreach (DevExpress.XtraTab.ViewInfo.BaseTabPageViewInfo page in viewInfo.HeaderInfo.VisiblePages)
{
Rectangle bounds = page.Bounds;
if (bounds.Width <= 0 || bounds.Height <= 0) continue;
- lastRight = Math.Max(lastRight, bounds.Right);
+ XtraTabPage tabPage = page.Page as XtraTabPage;
+ bool home = tabPage != null && tabPage.Name == "xtpFirst";
+ bool selected = page.Page == viewInfo.SelectedTabPage;
+ bool hover = page.IsHotState && !selected;
+ Color backColor = home
+ ? (hover ? Color.White : stripColor)
+ : (selected || hover ? Color.White : normalColor);
+ Color borderColor = selected ? selectedBorder : normalBorder;
+
+ // 相邻页签首尾紧贴,不再保留页签栏底色间隔;每个页签仍然
+ // 单独绘制完整矩形边框,因此无间距时也能保持清晰边界。
+ int surfaceLeft = bounds.Left;
+ int surfaceRight = bounds.Right;
+ int surfaceTop = header.Top + 1;
+ int surfaceBottom = Math.Max(surfaceTop, dividerY - 1);
+ Rectangle surface = Rectangle.FromLTRB(surfaceLeft, surfaceTop,
+ Math.Max(surfaceLeft + 1, surfaceRight), surfaceBottom + 1);
+ using (Brush brush = new SolidBrush(backColor))
+ graphics.FillRectangle(brush, surface);
using (Pen pen = new Pen(borderColor))
{
- // 明确绘制页签左右分隔及顶部边线,避免 DevExpress 不同皮肤
- // 忽略 Appearance.BorderColor 后多个白色页签连成一片。
- e.Graphics.DrawLine(pen, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 1);
- e.Graphics.DrawLine(pen, bounds.Right - 1, bounds.Top, bounds.Right - 1, bounds.Bottom - 1);
- e.Graphics.DrawLine(pen, bounds.Left, bounds.Top, bounds.Right - 1, bounds.Top);
+ // 为每个页签单独绘制完整矩形。WPF 通过相邻边框、页签间距
+ // 和底部 Divider 共同形成矩形;WinForms 直接绘制四边可避免
+ // DevExpress 皮肤把多个未选中页签合并成一个整体。
+ graphics.DrawRectangle(pen, surface.Left, surface.Top,
+ Math.Max(0, surface.Width - 1), Math.Max(0, surface.Height - 1));
+ }
+
+ Rectangle closeBounds = page.ControlBox;
+ int textLeft = surface.Left + (home ? 34 : 12);
+ int textRight = closeBounds.Width > 0 ? closeBounds.Left - 6 : surface.Right - 8;
+ Rectangle textBounds = new Rectangle(textLeft, surface.Top,
+ Math.Max(1, textRight - textLeft), surface.Height);
+ Color textColor = !home && selected ? selectedText : normalText;
+ TextRenderer.DrawText(graphics, page.Page.Text, tabs.AppearancePage.Header.Font,
+ textBounds, textColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter |
+ TextFormatFlags.SingleLine | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix);
+
+ if (closeBounds.Width > 0 && closeBounds.Height > 0)
+ {
+ bool closeHot = closeBounds.Contains(tabs.PointToClient(WinFormsControl.MousePosition));
+ if (closeHot)
+ {
+ using (Brush brush = new SolidBrush(Color.FromArgb(234, 242, 251)))
+ graphics.FillRectangle(brush, closeBounds);
+ }
+ int cx = closeBounds.Left + closeBounds.Width / 2;
+ int cy = closeBounds.Top + closeBounds.Height / 2;
+ using (Pen pen = new Pen(Color.FromArgb(127, 143, 163)))
+ {
+ graphics.DrawLine(pen, cx - 3, cy - 3, cx + 3, cy + 3);
+ graphics.DrawLine(pen, cx + 3, cy - 3, cx - 3, cy + 3);
+ }
}
}
- // WPF 页签后方是浅灰色页签带,而不是与内容区相同的纯白色。
- Rectangle buttons = viewInfo.HeaderInfo.ButtonsBounds;
- int emptyRight = buttons.Width > 0 ? buttons.Left : header.Right;
- if (lastRight < emptyRight)
- {
- using (Brush brush = new SolidBrush(stripColor))
- e.Graphics.FillRectangle(brush, lastRight, header.Top, emptyRight - lastRight, header.Height);
- }
- // WPF 在整个 WorkspaceTabStrip 底部单独覆盖一条 1px 的 #C7D3E4
- // 分隔线。不能沿用 HeaderInfo.Bounds.Bottom:旧版 DevExpress 中该位置
- // 仍可能属于页签头内部,线条会与页签背景混在一起。这里按内容区顶部定位,
- // 横跨控件全宽,并增加一条极浅下沿,使 WinForms 在不同 DPI 下仍有边界感。
- Rectangle pageClient = tabs.PageClientBounds;
- int dividerY = pageClient.Top > 0 ? pageClient.Top - 1 : header.Bottom - 1;
- dividerY = Math.Max(0, Math.Min(tabs.ClientSize.Height - 1, dividerY));
- using (Pen pen = new Pen(borderColor))
- e.Graphics.DrawLine(pen, 0, dividerY, tabs.ClientSize.Width - 1, dividerY);
- if (dividerY + 1 < tabs.ClientSize.Height)
- {
- using (Pen pen = new Pen(Color.FromArgb(237, 242, 247)))
- e.Graphics.DrawLine(pen, 0, dividerY + 1, tabs.ClientSize.Width - 1, dividerY + 1);
- }
+ // 与 WPF WorkspaceTabStripDivider 一致,最上层覆盖 1px #C7D3E4。
+ using (Pen pen = new Pen(selectedBorder))
+ graphics.DrawLine(pen, 0, dividerY, tabs.ClientSize.Width - 1, dividerY);
}
private static void ConfigureTabAppearance(DevExpress.Utils.AppearanceObject appearance, Color backColor, Color foreColor, Color borderColor)
@@ -253,16 +356,16 @@ namespace Lskj.Main.Control
}
}
- private void StyleTopNavigation(MenuStrip menu)
+ private void StyleTopNavigation(MenuStrip menu, Color headerColor, int topFontSize)
{
- menu.Renderer = new WpfMenuRenderer(HeaderColor, () =>
+ menu.Renderer = new WpfMenuRenderer(headerColor, () =>
{
// 每次绘制都重新读取当前导航,支持旧版双击或其它入口切换目录。
return FindCurrentTopMenu(menu) ?? _selectedTopMenu;
});
- menu.BackColor = HeaderColor;
+ menu.BackColor = headerColor;
menu.ForeColor = Color.FromArgb(242, 246, 255);
- menu.Font = new Font("微软雅黑", 10F);
+ menu.Font = new Font("微软雅黑", GetConfiguredFontSize(topFontSize, 9F));
menu.Dock = DockStyle.Fill;
menu.Location = Point.Empty;
menu.Padding = new Padding(4, 0, 4, 0);
@@ -416,34 +519,38 @@ namespace Lskj.Main.Control
if (oldTitle != null) oldTitle.Visible = false;
}
- private void StyleSidebar()
+ private void StyleSidebar(MainAppearanceSettings appearance)
{
Panel sidebar = FindControl("pl_center_left");
if (sidebar == null) return;
+ Color sidebarColor = GetConfiguredColor(appearance.SidebarBackground, SidebarColor);
+ Color sidebarSelectedColor = GetConfiguredColor(appearance.SidebarSelectedBackground, SidebarSelectedColor);
+ Color sidebarHoverColor = GetHoverColor(sidebarColor);
+ float sidebarFontSize = GetConfiguredFontSize(appearance.LeftMenuFontSize, 12F);
// 新版侧栏对应旧程序的 MainLeftShowMode=1(分组树菜单)配置。
bool useGroupedSidebar = IsGroupedSidebarMode();
- sidebar.Width = 176; sidebar.Padding = Padding.Empty; sidebar.BackColor = SidebarColor; sidebar.AutoScroll = true;
+ sidebar.Width = 176; sidebar.Padding = Padding.Empty; sidebar.BackColor = sidebarColor; sidebar.AutoScroll = true;
if (!useGroupedSidebar) return;
foreach (TreeList tree in FindControls(sidebar))
{
- tree.Dock = DockStyle.Fill; tree.RowHeight = 44; tree.BackColor = SidebarColor;
- tree.Appearance.Empty.BackColor = SidebarColor; tree.Appearance.Empty.Options.UseBackColor = true;
- tree.Appearance.Row.BackColor = SidebarColor; tree.Appearance.Row.ForeColor = Color.FromArgb(235, 255, 255, 255);
- tree.Appearance.Row.Font = new Font("微软雅黑", 10F); tree.Appearance.Row.Options.UseBackColor = true;
+ tree.Dock = DockStyle.Fill; tree.RowHeight = 44; tree.BackColor = sidebarColor;
+ tree.Appearance.Empty.BackColor = sidebarColor; tree.Appearance.Empty.Options.UseBackColor = true;
+ tree.Appearance.Row.BackColor = sidebarColor; tree.Appearance.Row.ForeColor = Color.FromArgb(235, 255, 255, 255);
+ tree.Appearance.Row.Font = new Font("微软雅黑", sidebarFontSize); tree.Appearance.Row.Options.UseBackColor = true;
tree.Appearance.Row.Options.UseForeColor = true; tree.Appearance.Row.Options.UseFont = true;
- tree.Appearance.FocusedRow.BackColor = SidebarSelectedColor; tree.Appearance.FocusedRow.ForeColor = Color.White;
+ tree.Appearance.FocusedRow.BackColor = sidebarSelectedColor; tree.Appearance.FocusedRow.ForeColor = Color.White;
tree.Appearance.FocusedRow.Options.UseBackColor = true; tree.Appearance.FocusedRow.Options.UseForeColor = true;
- tree.Appearance.HideSelectionRow.BackColor = SidebarSelectedColor; tree.Appearance.HideSelectionRow.ForeColor = Color.White;
+ tree.Appearance.HideSelectionRow.BackColor = sidebarSelectedColor; tree.Appearance.HideSelectionRow.ForeColor = Color.White;
tree.Appearance.HideSelectionRow.Options.UseBackColor = true; tree.Appearance.HideSelectionRow.Options.UseForeColor = true;
tree.OptionsView.ShowColumns = false; tree.OptionsView.ShowIndicator = false; tree.OptionsView.ShowHorzLines = false; tree.OptionsView.ShowVertLines = false;
}
foreach (MenuBar menuBar in FindControls(sidebar))
{
- Button button = menuBar.GetButton(); menuBar.BackColor = SidebarColor; menuBar.Height = 44;
- button.Dock = DockStyle.Fill; button.BackColor = SidebarColor; button.BackgroundImage = null;
+ Button button = menuBar.GetButton(); menuBar.BackColor = sidebarColor; menuBar.Height = 44;
+ button.Dock = DockStyle.Fill; button.BackColor = sidebarColor; button.BackgroundImage = null;
button.FlatStyle = FlatStyle.Flat; button.FlatAppearance.BorderSize = 0;
- button.FlatAppearance.MouseOverBackColor = Color.FromArgb(74, 80, 108); button.FlatAppearance.MouseDownBackColor = SidebarSelectedColor;
- button.ForeColor = Color.FromArgb(235, 255, 255, 255); button.Font = new Font("微软雅黑", 10F);
+ button.FlatAppearance.MouseOverBackColor = sidebarHoverColor; button.FlatAppearance.MouseDownBackColor = sidebarSelectedColor;
+ button.ForeColor = Color.FromArgb(235, 255, 255, 255); button.Font = new Font("微软雅黑", sidebarFontSize);
button.TextAlign = ContentAlignment.MiddleLeft; button.Padding = new Padding(20, 0, 12, 0);
button.Click -= SidebarButton_Click;
button.Click += SidebarButton_Click;
@@ -454,11 +561,14 @@ namespace Lskj.Main.Control
{
Button selected = sender as Button;
if (selected == null) return;
+ MainAppearanceSettings appearance = MainAppearanceSettingsStore.Load();
+ Color sidebarColor = GetConfiguredColor(appearance.SidebarBackground, SidebarColor);
+ Color sidebarSelectedColor = GetConfiguredColor(appearance.SidebarSelectedBackground, SidebarSelectedColor);
Panel sidebar = FindControl("pl_center_left");
foreach (Button button in FindControls