feat: 完善个人设置及表格功能
This commit is contained in:
@@ -342,12 +342,17 @@ namespace Lskj.Business
|
|||||||
Instance.IsSpecialAuditSave = item.Table.Columns.Contains("IsSpecialAuditSave") && !string.IsNullOrEmpty(item["IsSpecialAuditSave"] + "") ? "1".Equals(item["IsSpecialAuditSave"] + "") : false;
|
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;
|
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 = item.Table.Columns.Contains("NewMain") && !string.IsNullOrEmpty(item["NewMain"] + "") ? "1".Equals(item["NewMain"] + "") : false;
|
||||||
Instance.NewMain = "1".Equals(newMainValue) || "true".Equals(newMainValue, StringComparison.OrdinalIgnoreCase);
|
|
||||||
if (Instance.NewMain)
|
if (Instance.NewMain)
|
||||||
{
|
{
|
||||||
Instance.MainLeftShowMode = "1";
|
Instance.MainLeftShowMode = "1";
|
||||||
Instance.DefaultMainTag = 4;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1203,13 +1208,17 @@ namespace Lskj.Business
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string MainLeftColor;
|
public string MainLeftColor;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 新版界面左侧选中背景色
|
||||||
|
/// </summary>
|
||||||
|
public string MainLeftSelectColor;
|
||||||
|
/// <summary>
|
||||||
/// 新版界面顶部字体大小
|
/// 新版界面顶部字体大小
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string MainTopFontSize;
|
public int MainTopFontSize;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 新版界面左侧字体大小
|
/// 新版界面左侧字体大小
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string MainLeftFontSize;
|
public int MainLeftFontSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ namespace Lskj.Control
|
|||||||
this.bandedGridView.PopupMenuShowing += new DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventHandler(this.OnGridViewPopupMenuShowing);
|
this.bandedGridView.PopupMenuShowing += new DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventHandler(this.OnGridViewPopupMenuShowing);
|
||||||
this.bandedGridView.Click += new EventHandler(OnBandedGridView_Click);
|
this.bandedGridView.Click += new EventHandler(OnBandedGridView_Click);
|
||||||
this.bandedGridView.DoubleClick += new EventHandler(OnBandedGridViewDoubleClick);
|
this.bandedGridView.DoubleClick += new EventHandler(OnBandedGridViewDoubleClick);
|
||||||
|
// 多表头的操作列使用 BandedGridView,复用基类的禁编按钮点击处理。
|
||||||
|
this.bandedGridView.MouseDown += GridView_MouseDown;
|
||||||
this.bandedGridView.CustomDrawGroupRow += new RowObjectCustomDrawEventHandler(OnGridCustomDrawGroupRow);
|
this.bandedGridView.CustomDrawGroupRow += new RowObjectCustomDrawEventHandler(OnGridCustomDrawGroupRow);
|
||||||
this.bandedGridView.LeftCoordChanged += OnBandedLeftCoordChanged;
|
this.bandedGridView.LeftCoordChanged += OnBandedLeftCoordChanged;
|
||||||
this.SetGridRowHeightAndFont();
|
this.SetGridRowHeightAndFont();
|
||||||
@@ -133,6 +135,236 @@ namespace Lskj.Control
|
|||||||
this.bandedGridView.ShowingEditor += GridView_ShowingEditor;
|
this.bandedGridView.ShowingEditor += GridView_ShowingEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 多表头创建或重建操作列。
|
||||||
|
/// 操作列不参与业务列配置,只挂到空白一级表头的最右侧。
|
||||||
|
/// </summary>
|
||||||
|
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<DataRow>().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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除旧操作列,同时保持空白一级表头下其他列的现有宽度。
|
||||||
|
/// </summary>
|
||||||
|
private void RemoveRightMenuButtonColumn(BandedGridColumn oldColumn)
|
||||||
|
{
|
||||||
|
GridBand ownerBand = oldColumn.OwnerBand;
|
||||||
|
int oldColumnWidth = oldColumn.Width;
|
||||||
|
int originalBandWidth = ownerBand == null ? 0 : ownerBand.Width;
|
||||||
|
Dictionary<BandedGridColumn, int> originalColumnWidths = ownerBand == null
|
||||||
|
? new Dictionary<BandedGridColumn, int>()
|
||||||
|
: ownerBand.Columns.Cast<BandedGridColumn>()
|
||||||
|
.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<BandedGridColumn, int> item in originalColumnWidths)
|
||||||
|
{
|
||||||
|
item.Key.Width = item.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.bandedGridView.EndUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建多表头操作列,并将其放到空白一级表头的最右侧。
|
||||||
|
/// </summary>
|
||||||
|
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<GridBand>()
|
||||||
|
.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<BandedGridColumn, int> originalColumnWidths = emptyBand.Columns
|
||||||
|
.Cast<BandedGridColumn>()
|
||||||
|
.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<BandedGridColumn, int> item in originalColumnWidths)
|
||||||
|
{
|
||||||
|
item.Key.Width = item.Value;
|
||||||
|
}
|
||||||
|
gridColumn.Width = columnWidth;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.bandedGridView.EndUpdate();
|
||||||
|
}
|
||||||
|
this.bandedGridView.OptionsBehavior.EditorShowMode = EditorShowMode.MouseDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -574,6 +806,7 @@ namespace Lskj.Control
|
|||||||
protected void AddBandColumns(DataTable table, bool readOnly = true)
|
protected void AddBandColumns(DataTable table, bool readOnly = true)
|
||||||
{
|
{
|
||||||
if (table == null) return;
|
if (table == null) return;
|
||||||
|
this.gridColumnsInitialized = false;
|
||||||
this.InitGridColumsTab = table;
|
this.InitGridColumsTab = table;
|
||||||
this.mControlList.Clear();
|
this.mControlList.Clear();
|
||||||
List<String> bandFieldstr = new List<String>();
|
List<String> bandFieldstr = new List<String>();
|
||||||
@@ -844,6 +1077,8 @@ namespace Lskj.Control
|
|||||||
// 加载数据源
|
// 加载数据源
|
||||||
//BindDataSource();
|
//BindDataSource();
|
||||||
this.SetCustomColumns();//加载多表头自定义列
|
this.SetCustomColumns();//加载多表头自定义列
|
||||||
|
this.gridColumnsInitialized = true;
|
||||||
|
this.TryInitRightMenuBtnEdit(false);
|
||||||
|
|
||||||
//多表头冻结
|
//多表头冻结
|
||||||
foreach (BandedGridColumn item in FrozenColumns)
|
foreach (BandedGridColumn item in FrozenColumns)
|
||||||
|
|||||||
@@ -178,6 +178,12 @@ namespace Lskj.Control
|
|||||||
|
|
||||||
foreach (GridColumn col in gridView.Columns)
|
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)) ||
|
if ((col.ColumnEdit != null && col.ColumnEdit.GetType() == typeof(RepositoryItemCheckEdit)) ||
|
||||||
(col.ColumnType != null && col.ColumnType.Name.ToLower() == "boolean"))
|
(col.ColumnType != null && col.ColumnType.Name.ToLower() == "boolean"))
|
||||||
{
|
{
|
||||||
@@ -209,7 +215,7 @@ namespace Lskj.Control
|
|||||||
foreach (BandedGridColumn col in gridView.Columns)
|
foreach (BandedGridColumn col in gridView.Columns)
|
||||||
{
|
{
|
||||||
GridColumnModel gridModel = col.Tag as GridColumnModel;
|
GridColumnModel gridModel = col.Tag as GridColumnModel;
|
||||||
if (col.Visible)
|
if (col.Visible && !col.FieldName.Equals("RightMenuBtnEdit", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
BandedGridColumn newCol = new BandedGridColumn();
|
BandedGridColumn newCol = new BandedGridColumn();
|
||||||
newCol.Tag = col.Tag;
|
newCol.Tag = col.Tag;
|
||||||
|
|||||||
@@ -184,8 +184,8 @@ namespace Lskj.Control
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 外部设置的右键菜单数据,用于创建每行操作列。
|
/// 外部设置的右键菜单数据,用于创建每行操作列。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private DataTable rightMenuButtonTable;
|
protected DataTable rightMenuButtonTable;
|
||||||
private bool gridColumnsInitialized;
|
protected bool gridColumnsInitialized;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 新版模块选择框缓存。同一关联模块的单选和多选界面分别复用。
|
/// 新版模块选择框缓存。同一关联模块的单选和多选界面分别复用。
|
||||||
@@ -5649,8 +5649,8 @@ namespace Lskj.Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal void SetRightMenuButtonTable(DataTable table)
|
internal void SetRightMenuButtonTable(DataTable table)
|
||||||
{
|
{
|
||||||
// 树表格和多表头表格原来不在此处创建操作列,维持原有行为。
|
// 树表格仍由原有逻辑处理,不创建操作列。
|
||||||
if (this is TreeGridControlEx || this is BandedGridControlEx)
|
if (this is TreeGridControlEx)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5659,7 +5659,7 @@ namespace Lskj.Control
|
|||||||
this.TryInitRightMenuBtnEdit(true);
|
this.TryInitRightMenuBtnEdit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryInitRightMenuBtnEdit(bool rebuild)
|
protected virtual void TryInitRightMenuBtnEdit(bool rebuild)
|
||||||
{
|
{
|
||||||
if (!this.gridColumnsInitialized || this.Model == null ||
|
if (!this.gridColumnsInitialized || this.Model == null ||
|
||||||
this.CustomColumKey.Contains("BaseLeftGridView_"))
|
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 gridColumn = new GridColumn();
|
||||||
gridColumn.FieldName = "RightMenuBtnEdit";
|
gridColumn.FieldName = "RightMenuBtnEdit";
|
||||||
@@ -9771,7 +9771,7 @@ namespace Lskj.Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void OnItemButtonEdit_ButtonClick(object sender, ButtonPressedEventArgs e)
|
protected void OnItemButtonEdit_ButtonClick(object sender, ButtonPressedEventArgs e)
|
||||||
{
|
{
|
||||||
EditorButton editorButton = e.Button as EditorButton;
|
EditorButton editorButton = e.Button as EditorButton;
|
||||||
GridRightMenuModel menuModel = editorButton.Tag as GridRightMenuModel;
|
GridRightMenuModel menuModel = editorButton.Tag as GridRightMenuModel;
|
||||||
@@ -9779,8 +9779,8 @@ namespace Lskj.Control
|
|||||||
if (toolStripMenuItem != null)
|
if (toolStripMenuItem != null)
|
||||||
{
|
{
|
||||||
bool allowClick = true;
|
bool allowClick = true;
|
||||||
int[] mSelectRows = this.gridView.GetSelectedRows();
|
int[] mSelectRows = this.GridView.GetSelectedRows();
|
||||||
DataRow mSelectRow = this.gridView.GetDataRow(mSelectRows[0]);
|
DataRow mSelectRow = this.GridView.GetDataRow(mSelectRows[0]);
|
||||||
if (menuModel != null)
|
if (menuModel != null)
|
||||||
{
|
{
|
||||||
if (menuModel.PrivilegeOper.Length > 1 && !menuModel.PrivilegeOper.Contains(ERPInfo.Instance.UserName + ","))
|
if (menuModel.PrivilegeOper.Length > 1 && !menuModel.PrivilegeOper.Contains(ERPInfo.Instance.UserName + ","))
|
||||||
@@ -9797,13 +9797,13 @@ namespace Lskj.Control
|
|||||||
if (this.gridViewRightMenu.ControlObj != null)
|
if (this.gridViewRightMenu.ControlObj != null)
|
||||||
cond = this.gridViewRightMenu.ControlObj.ReplaceParentControlValue(menuModel.MenuCond);
|
cond = this.gridViewRightMenu.ControlObj.ReplaceParentControlValue(menuModel.MenuCond);
|
||||||
cond = ReplaceHelper.ReplaceRowParam(mSelectRow, 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_"))
|
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
|
||||||
{
|
{
|
||||||
GridCell cell = cells[0];
|
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] + "";
|
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);
|
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
|
||||||
}
|
}
|
||||||
@@ -11113,7 +11113,7 @@ namespace Lskj.Control
|
|||||||
return Math.Max(textWidth + padding, 40);
|
return Math.Max(textWidth + padding, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image GetRightMenuButtonImage(string imageName)
|
protected Image GetRightMenuButtonImage(string imageName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(imageName))
|
if (string.IsNullOrWhiteSpace(imageName))
|
||||||
{
|
{
|
||||||
@@ -11177,7 +11177,7 @@ namespace Lskj.Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void GridView_MouseDown(object sender, MouseEventArgs e)
|
protected void GridView_MouseDown(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Button != MouseButtons.Left) return;
|
if (e.Button != MouseButtons.Left) return;
|
||||||
|
|
||||||
@@ -11190,7 +11190,7 @@ namespace Lskj.Control
|
|||||||
RepositoryItemButtonEdit repo = hitInfo.Column.ColumnEdit as RepositoryItemButtonEdit;
|
RepositoryItemButtonEdit repo = hitInfo.Column.ColumnEdit as RepositoryItemButtonEdit;
|
||||||
if (!hitInfo.Column.FieldName.Equals("RightMenuBtnEdit")) return;
|
if (!hitInfo.Column.FieldName.Equals("RightMenuBtnEdit")) return;
|
||||||
int rowHandle = hitInfo.RowHandle;
|
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);
|
int buttonIndex = this.GetClickedButtonIndex(repo, view, rowHandle, hitInfo.Column, e.Location, hitInfo.Column.Width);
|
||||||
|
|
||||||
if (buttonIndex != -1)
|
if (buttonIndex != -1)
|
||||||
@@ -11207,7 +11207,7 @@ namespace Lskj.Control
|
|||||||
/// 执行点击的右键按钮
|
/// 执行点击的右键按钮
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="editorButton"></param>
|
/// <param name="editorButton"></param>
|
||||||
private void RightButtonClick(EditorButton editorButton)
|
protected void RightButtonClick(EditorButton editorButton)
|
||||||
{
|
{
|
||||||
|
|
||||||
GridRightMenuModel menuModel = editorButton.Tag as GridRightMenuModel;
|
GridRightMenuModel menuModel = editorButton.Tag as GridRightMenuModel;
|
||||||
@@ -11215,8 +11215,8 @@ namespace Lskj.Control
|
|||||||
if (toolStripMenuItem != null)
|
if (toolStripMenuItem != null)
|
||||||
{
|
{
|
||||||
bool allowClick = true;
|
bool allowClick = true;
|
||||||
int[] mSelectRows = this.gridView.GetSelectedRows();
|
int[] mSelectRows = this.GridView.GetSelectedRows();
|
||||||
DataRow mSelectRow = this.gridView.GetDataRow(mSelectRows[0]);
|
DataRow mSelectRow = this.GridView.GetDataRow(mSelectRows[0]);
|
||||||
if (menuModel != null)
|
if (menuModel != null)
|
||||||
{
|
{
|
||||||
if (menuModel.PrivilegeOper.Length > 1 && !menuModel.PrivilegeOper.Contains(ERPInfo.Instance.UserName + ","))
|
if (menuModel.PrivilegeOper.Length > 1 && !menuModel.PrivilegeOper.Contains(ERPInfo.Instance.UserName + ","))
|
||||||
@@ -11233,13 +11233,13 @@ namespace Lskj.Control
|
|||||||
if (this.gridViewRightMenu.ControlObj != null)
|
if (this.gridViewRightMenu.ControlObj != null)
|
||||||
cond = this.gridViewRightMenu.ControlObj.ReplaceParentControlValue(menuModel.MenuCond);
|
cond = this.gridViewRightMenu.ControlObj.ReplaceParentControlValue(menuModel.MenuCond);
|
||||||
cond = ReplaceHelper.ReplaceRowParam(mSelectRow, 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_"))
|
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
|
||||||
{
|
{
|
||||||
GridCell cell = cells[0];
|
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] + "";
|
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);
|
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -622,6 +622,8 @@ namespace Lskj.Control.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridColumnModel model = col.Tag as GridColumnModel;
|
GridColumnModel model = col.Tag as GridColumnModel;
|
||||||
|
// 操作列是运行时创建的界面列,不参与个性化保存。
|
||||||
|
if (model == null) continue;
|
||||||
DataRow a = customTable.Rows.Cast<DataRow>().FirstOrDefault(x => col.Name.Equals(x["fieldName"] + "", StringComparison.OrdinalIgnoreCase));
|
DataRow a = customTable.Rows.Cast<DataRow>().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});",
|
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}';",
|
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;
|
gridControl.gridViewRightMenu = rightMenu;
|
||||||
rightMenu.InitRightMenus(gridControl, table, model, control, menu);
|
rightMenu.InitRightMenus(gridControl, table, model, control, menu);
|
||||||
rightMenu.SetRightCallback(handler);
|
rightMenu.SetRightCallback(handler);
|
||||||
|
// 右键菜单创建完成后再生成多表头操作列,确保按钮数据完整。
|
||||||
|
gridControl.SetRightMenuButtonTable(table);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>说明:设置图标右键菜单</para>
|
/// <para>说明:设置图标右键菜单</para>
|
||||||
|
|||||||
@@ -358,6 +358,11 @@ namespace Lskj.Control
|
|||||||
tcButtom.OnDetailRightCallback += OnGridViewRightCallBack;
|
tcButtom.OnDetailRightCallback += OnGridViewRightCallBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.SysModel.RefreshTheInterface)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
this.tcButtom.Model = this.Model;
|
this.tcButtom.Model = this.Model;
|
||||||
this.tcButtom.DrgaParentPrimaryKey = this.SysModel.ParmaryKey;
|
this.tcButtom.DrgaParentPrimaryKey = this.SysModel.ParmaryKey;
|
||||||
this.tcButtom.IsDragDetail = this.IsDragDetail;
|
this.tcButtom.IsDragDetail = this.IsDragDetail;
|
||||||
@@ -387,6 +392,11 @@ namespace Lskj.Control
|
|||||||
tcButtom.OnDetailRightCallback += OnGridViewRightCallBack;
|
tcButtom.OnDetailRightCallback += OnGridViewRightCallBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.SysModel.RefreshTheInterface)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
this.tcButtom.Model = this.Model;
|
this.tcButtom.Model = this.Model;
|
||||||
this.tcButtom.DrgaParentPrimaryKey = this.SysModel.ParmaryKey;
|
this.tcButtom.DrgaParentPrimaryKey = this.SysModel.ParmaryKey;
|
||||||
this.tcButtom.IsDragDetail = this.IsDragDetail;
|
this.tcButtom.IsDragDetail = this.IsDragDetail;
|
||||||
|
|||||||
@@ -142,6 +142,13 @@ namespace Lskj.Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler BillDetailRightGridCallBack;
|
public event EventHandler BillDetailRightGridCallBack;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新版左右结构下,左侧或者右侧的表格数据改变后,刷新主表数据(主表刷新后会刷新当前明细或者全部明细)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
public event EventHandler OnDataChangeExecution;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 明细页签与主模块对应关系
|
/// 明细页签与主模块对应关系
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -181,6 +188,9 @@ namespace Lskj.Control
|
|||||||
/// 页签名(判断是否有重复的左右结构)
|
/// 页签名(判断是否有重复的左右结构)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DetaiName = string.Empty;
|
public string DetaiName = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TabControlEx()
|
public TabControlEx()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|||||||
+304
-61
@@ -5,6 +5,7 @@ using System.ComponentModel;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -12,6 +13,7 @@ using System.Windows.Forms;
|
|||||||
using DevExpress.XtraTab;
|
using DevExpress.XtraTab;
|
||||||
using DevExpress.XtraTreeList;
|
using DevExpress.XtraTreeList;
|
||||||
using Lskj.Business;
|
using Lskj.Business;
|
||||||
|
using Lskj.Main;
|
||||||
using Lskj.Model;
|
using Lskj.Model;
|
||||||
using WinFormsControl = System.Windows.Forms.Control;
|
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 static readonly Color ShortcutBorderColor = Color.FromArgb(221, 227, 234);
|
||||||
private System.ComponentModel.IContainer components = null;
|
private System.ComponentModel.IContainer components = null;
|
||||||
private MainPanelControlEx _legacyPanel;
|
private MainPanelControlEx _legacyPanel;
|
||||||
|
private MainTabsNativeWindow _mainTabsNativeWindow;
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
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);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,35 +69,37 @@ namespace Lskj.Main.Control
|
|||||||
#region 新版主界面外观
|
#region 新版主界面外观
|
||||||
private void ApplyWpfShellStyle()
|
private void ApplyWpfShellStyle()
|
||||||
{
|
{
|
||||||
|
MainAppearanceSettings appearance = MainAppearanceSettingsStore.Load();
|
||||||
|
Color headerColor = GetConfiguredColor(appearance.TopMenuBackground, HeaderColor);
|
||||||
Panel header = FindControl<Panel>("plTop");
|
Panel header = FindControl<Panel>("plTop");
|
||||||
Panel headerLeft = FindControl<Panel>("pl_top_left");
|
Panel headerLeft = FindControl<Panel>("pl_top_left");
|
||||||
Panel headerCenter = FindControl<Panel>("pl_top_center");
|
Panel headerCenter = FindControl<Panel>("pl_top_center");
|
||||||
Panel headerRight = FindControl<Panel>("pl_top_right");
|
Panel headerRight = FindControl<Panel>("pl_top_right");
|
||||||
Panel headerSeparator = FindControl<Panel>("panel3");
|
Panel headerSeparator = FindControl<Panel>("panel3");
|
||||||
MenuStrip topMenu = FindControl<MenuStrip>("menuMain");
|
MenuStrip topMenu = FindControl<MenuStrip>("menuMain");
|
||||||
if (header != null) { header.Height = 50; header.BackColor = HeaderColor; }
|
if (header != null) { header.Height = 50; header.BackColor = headerColor; }
|
||||||
if (headerLeft != null)
|
if (headerLeft != null)
|
||||||
{
|
{
|
||||||
headerLeft.Width = 176;
|
headerLeft.Width = 176;
|
||||||
headerLeft.BackColor = HeaderColor;
|
headerLeft.BackColor = headerColor;
|
||||||
headerLeft.BackgroundImage = null;
|
headerLeft.BackgroundImage = null;
|
||||||
AddBrandVisual(headerLeft);
|
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 顶部栏是连续布局,
|
// 旧版 Logo 与菜单之间有 19px 的装饰分隔面板;WPF 顶部栏是连续布局,
|
||||||
// 保留该控件会在两块蓝色之间形成突兀的深色竖条。
|
// 保留该控件会在两块蓝色之间形成突兀的深色竖条。
|
||||||
if (headerSeparator != null)
|
if (headerSeparator != null)
|
||||||
{
|
{
|
||||||
headerSeparator.Width = 0;
|
headerSeparator.Width = 0;
|
||||||
headerSeparator.BackColor = HeaderColor;
|
headerSeparator.BackColor = headerColor;
|
||||||
headerSeparator.BackgroundImage = null;
|
headerSeparator.BackgroundImage = null;
|
||||||
}
|
}
|
||||||
StyleSearchControls();
|
StyleSearchControls();
|
||||||
if (topMenu != null) StyleTopNavigation(topMenu);
|
if (topMenu != null) StyleTopNavigation(topMenu, headerColor, appearance.TopMenuFontSize);
|
||||||
StyleMainTabs();
|
StyleMainTabs();
|
||||||
StyleSidebar();
|
StyleSidebar(appearance);
|
||||||
StyleWorkspaceAndShortcuts();
|
StyleWorkspaceAndShortcuts();
|
||||||
RememberStyledNavigation();
|
RememberStyledNavigation();
|
||||||
}
|
}
|
||||||
@@ -147,8 +156,13 @@ namespace Lskj.Main.Control
|
|||||||
Color tabHover = Color.White;
|
Color tabHover = Color.White;
|
||||||
Color tabBorder = Color.FromArgb(199, 211, 228);
|
Color tabBorder = Color.FromArgb(199, 211, 228);
|
||||||
tabs.PaintStyleName = "Flat";
|
tabs.PaintStyleName = "Flat";
|
||||||
|
tabs.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||||
|
tabs.BorderStylePage = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
|
||||||
tabs.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Top;
|
tabs.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Top;
|
||||||
tabs.HeaderAutoFill = DevExpress.Utils.DefaultBoolean.False;
|
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.TabPageWidth = 0;
|
||||||
tabs.BackColor = tabStrip;
|
tabs.BackColor = tabStrip;
|
||||||
tabs.Appearance.BackColor = tabStrip;
|
tabs.Appearance.BackColor = tabStrip;
|
||||||
@@ -162,18 +176,69 @@ namespace Lskj.Main.Control
|
|||||||
tabs.AppearancePage.HeaderHotTracked.Font = tabs.AppearancePage.Header.Font;
|
tabs.AppearancePage.HeaderHotTracked.Font = tabs.AppearancePage.Header.Font;
|
||||||
tabs.AppearancePage.HeaderDisabled.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;
|
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<XtraTabPage>().FirstOrDefault(p => p.Name == "xtpFirst");
|
XtraTabPage first = tabs.TabPages.Cast<XtraTabPage>().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)
|
private void MainTabs_Paint(object sender, PaintEventArgs e)
|
||||||
{
|
{
|
||||||
XtraTabControl tabs = sender as XtraTabControl;
|
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.IXtraTab tabInterface = tabs as DevExpress.XtraTab.IXtraTab;
|
||||||
DevExpress.XtraTab.ViewInfo.BaseTabControlViewInfo viewInfo =
|
DevExpress.XtraTab.ViewInfo.BaseTabControlViewInfo viewInfo =
|
||||||
tabInterface == null ? null : tabInterface.ViewInfo;
|
tabInterface == null ? null : tabInterface.ViewInfo;
|
||||||
@@ -181,47 +246,85 @@ namespace Lskj.Main.Control
|
|||||||
|
|
||||||
Rectangle header = viewInfo.HeaderInfo.Bounds;
|
Rectangle header = viewInfo.HeaderInfo.Bounds;
|
||||||
if (header.Width <= 0 || header.Height <= 0) return;
|
if (header.Width <= 0 || header.Height <= 0) return;
|
||||||
Color stripColor = Color.FromArgb(243, 245, 248);
|
Color stripColor = Color.FromArgb(243, 245, 248); // #F3F5F8
|
||||||
Color borderColor = Color.FromArgb(199, 211, 228);
|
Color normalColor = Color.FromArgb(248, 250, 252); // #F8FAFC
|
||||||
int lastRight = header.Left;
|
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)
|
foreach (DevExpress.XtraTab.ViewInfo.BaseTabPageViewInfo page in viewInfo.HeaderInfo.VisiblePages)
|
||||||
{
|
{
|
||||||
Rectangle bounds = page.Bounds;
|
Rectangle bounds = page.Bounds;
|
||||||
if (bounds.Width <= 0 || bounds.Height <= 0) continue;
|
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))
|
using (Pen pen = new Pen(borderColor))
|
||||||
{
|
{
|
||||||
// 明确绘制页签左右分隔及顶部边线,避免 DevExpress 不同皮肤
|
// 为每个页签单独绘制完整矩形。WPF 通过相邻边框、页签间距
|
||||||
// 忽略 Appearance.BorderColor 后多个白色页签连成一片。
|
// 和底部 Divider 共同形成矩形;WinForms 直接绘制四边可避免
|
||||||
e.Graphics.DrawLine(pen, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 1);
|
// DevExpress 皮肤把多个未选中页签合并成一个整体。
|
||||||
e.Graphics.DrawLine(pen, bounds.Right - 1, bounds.Top, bounds.Right - 1, bounds.Bottom - 1);
|
graphics.DrawRectangle(pen, surface.Left, surface.Top,
|
||||||
e.Graphics.DrawLine(pen, bounds.Left, bounds.Top, bounds.Right - 1, bounds.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 页签后方是浅灰色页签带,而不是与内容区相同的纯白色。
|
// 与 WPF WorkspaceTabStripDivider 一致,最上层覆盖 1px #C7D3E4。
|
||||||
Rectangle buttons = viewInfo.HeaderInfo.ButtonsBounds;
|
using (Pen pen = new Pen(selectedBorder))
|
||||||
int emptyRight = buttons.Width > 0 ? buttons.Left : header.Right;
|
graphics.DrawLine(pen, 0, dividerY, tabs.ClientSize.Width - 1, dividerY);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ConfigureTabAppearance(DevExpress.Utils.AppearanceObject appearance, Color backColor, Color foreColor, Color borderColor)
|
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;
|
return FindCurrentTopMenu(menu) ?? _selectedTopMenu;
|
||||||
});
|
});
|
||||||
menu.BackColor = HeaderColor;
|
menu.BackColor = headerColor;
|
||||||
menu.ForeColor = Color.FromArgb(242, 246, 255);
|
menu.ForeColor = Color.FromArgb(242, 246, 255);
|
||||||
menu.Font = new Font("微软雅黑", 10F);
|
menu.Font = new Font("微软雅黑", GetConfiguredFontSize(topFontSize, 9F));
|
||||||
menu.Dock = DockStyle.Fill;
|
menu.Dock = DockStyle.Fill;
|
||||||
menu.Location = Point.Empty;
|
menu.Location = Point.Empty;
|
||||||
menu.Padding = new Padding(4, 0, 4, 0);
|
menu.Padding = new Padding(4, 0, 4, 0);
|
||||||
@@ -416,34 +519,38 @@ namespace Lskj.Main.Control
|
|||||||
if (oldTitle != null) oldTitle.Visible = false;
|
if (oldTitle != null) oldTitle.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StyleSidebar()
|
private void StyleSidebar(MainAppearanceSettings appearance)
|
||||||
{
|
{
|
||||||
Panel sidebar = FindControl<Panel>("pl_center_left");
|
Panel sidebar = FindControl<Panel>("pl_center_left");
|
||||||
if (sidebar == null) return;
|
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(分组树菜单)配置。
|
// 新版侧栏对应旧程序的 MainLeftShowMode=1(分组树菜单)配置。
|
||||||
bool useGroupedSidebar = IsGroupedSidebarMode();
|
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;
|
if (!useGroupedSidebar) return;
|
||||||
foreach (TreeList tree in FindControls<TreeList>(sidebar))
|
foreach (TreeList tree in FindControls<TreeList>(sidebar))
|
||||||
{
|
{
|
||||||
tree.Dock = DockStyle.Fill; tree.RowHeight = 44; tree.BackColor = SidebarColor;
|
tree.Dock = DockStyle.Fill; tree.RowHeight = 44; tree.BackColor = sidebarColor;
|
||||||
tree.Appearance.Empty.BackColor = SidebarColor; tree.Appearance.Empty.Options.UseBackColor = true;
|
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.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.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.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.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.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;
|
tree.OptionsView.ShowColumns = false; tree.OptionsView.ShowIndicator = false; tree.OptionsView.ShowHorzLines = false; tree.OptionsView.ShowVertLines = false;
|
||||||
}
|
}
|
||||||
foreach (MenuBar menuBar in FindControls<MenuBar>(sidebar))
|
foreach (MenuBar menuBar in FindControls<MenuBar>(sidebar))
|
||||||
{
|
{
|
||||||
Button button = menuBar.GetButton(); menuBar.BackColor = SidebarColor; menuBar.Height = 44;
|
Button button = menuBar.GetButton(); menuBar.BackColor = sidebarColor; menuBar.Height = 44;
|
||||||
button.Dock = DockStyle.Fill; button.BackColor = SidebarColor; button.BackgroundImage = null;
|
button.Dock = DockStyle.Fill; button.BackColor = sidebarColor; button.BackgroundImage = null;
|
||||||
button.FlatStyle = FlatStyle.Flat; button.FlatAppearance.BorderSize = 0;
|
button.FlatStyle = FlatStyle.Flat; button.FlatAppearance.BorderSize = 0;
|
||||||
button.FlatAppearance.MouseOverBackColor = Color.FromArgb(74, 80, 108); button.FlatAppearance.MouseDownBackColor = SidebarSelectedColor;
|
button.FlatAppearance.MouseOverBackColor = sidebarHoverColor; button.FlatAppearance.MouseDownBackColor = sidebarSelectedColor;
|
||||||
button.ForeColor = Color.FromArgb(235, 255, 255, 255); button.Font = new Font("微软雅黑", 10F);
|
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.TextAlign = ContentAlignment.MiddleLeft; button.Padding = new Padding(20, 0, 12, 0);
|
||||||
button.Click -= SidebarButton_Click;
|
button.Click -= SidebarButton_Click;
|
||||||
button.Click += SidebarButton_Click;
|
button.Click += SidebarButton_Click;
|
||||||
@@ -454,11 +561,14 @@ namespace Lskj.Main.Control
|
|||||||
{
|
{
|
||||||
Button selected = sender as Button;
|
Button selected = sender as Button;
|
||||||
if (selected == null) return;
|
if (selected == null) return;
|
||||||
|
MainAppearanceSettings appearance = MainAppearanceSettingsStore.Load();
|
||||||
|
Color sidebarColor = GetConfiguredColor(appearance.SidebarBackground, SidebarColor);
|
||||||
|
Color sidebarSelectedColor = GetConfiguredColor(appearance.SidebarSelectedBackground, SidebarSelectedColor);
|
||||||
Panel sidebar = FindControl<Panel>("pl_center_left");
|
Panel sidebar = FindControl<Panel>("pl_center_left");
|
||||||
foreach (Button button in FindControls<Button>(sidebar))
|
foreach (Button button in FindControls<Button>(sidebar))
|
||||||
{
|
{
|
||||||
button.BackgroundImage = null;
|
button.BackgroundImage = null;
|
||||||
button.BackColor = button == selected ? SidebarSelectedColor : SidebarColor;
|
button.BackColor = button == selected ? sidebarSelectedColor : sidebarColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,6 +811,63 @@ namespace Lskj.Main.Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetSystemInfoText(string memberName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
object systemInfo = SystemInfo.Instance;
|
||||||
|
Type type = systemInfo.GetType();
|
||||||
|
FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public);
|
||||||
|
if (field != null) return Convert.ToString(field.GetValue(systemInfo), CultureInfo.InvariantCulture);
|
||||||
|
PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public);
|
||||||
|
if (property != null) return Convert.ToString(property.GetValue(systemInfo, null), CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// 配置成员不存在或读取失败时继续使用默认选中颜色。
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color GetConfiguredColor(string configuredValue, Color defaultColor)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(configuredValue)) return defaultColor;
|
||||||
|
string hex = configuredValue.Trim();
|
||||||
|
if (hex.StartsWith("#", StringComparison.Ordinal)) hex = hex.Substring(1);
|
||||||
|
|
||||||
|
uint value;
|
||||||
|
if (!uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value))
|
||||||
|
return defaultColor;
|
||||||
|
if (hex.Length == 6)
|
||||||
|
return Color.FromArgb((int)((value >> 16) & 0xFF), (int)((value >> 8) & 0xFF), (int)(value & 0xFF));
|
||||||
|
if (hex.Length == 8)
|
||||||
|
return Color.FromArgb((int)((value >> 24) & 0xFF), (int)((value >> 16) & 0xFF),
|
||||||
|
(int)((value >> 8) & 0xFF), (int)(value & 0xFF));
|
||||||
|
return defaultColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float GetConfiguredFontSize(object configuredValue, float defaultSize)
|
||||||
|
{
|
||||||
|
// SystemInfo 在数据库字段为空时写入 0;Font 不接受 0,因此正数才是有效配置。
|
||||||
|
float configuredSize;
|
||||||
|
string text = Convert.ToString(configuredValue, CultureInfo.InvariantCulture);
|
||||||
|
return float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out configuredSize)
|
||||||
|
&& configuredSize > 0
|
||||||
|
? configuredSize
|
||||||
|
: defaultSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color GetHoverColor(Color baseColor)
|
||||||
|
{
|
||||||
|
// 悬浮色跟随配置背景轻微提亮,避免自定义为橙色、红色等颜色后
|
||||||
|
// 仍出现旧版固定蓝灰色块。
|
||||||
|
const int percent = 8;
|
||||||
|
return Color.FromArgb(baseColor.A,
|
||||||
|
baseColor.R + (255 - baseColor.R) * percent / 100,
|
||||||
|
baseColor.G + (255 - baseColor.G) * percent / 100,
|
||||||
|
baseColor.B + (255 - baseColor.B) * percent / 100);
|
||||||
|
}
|
||||||
|
|
||||||
private T FindControl<T>(string name) where T : WinFormsControl { return Controls.Find(name, true).OfType<T>().FirstOrDefault(); }
|
private T FindControl<T>(string name) where T : WinFormsControl { return Controls.Find(name, true).OfType<T>().FirstOrDefault(); }
|
||||||
|
|
||||||
private static IEnumerable<T> FindControls<T>(WinFormsControl root) where T : WinFormsControl
|
private static IEnumerable<T> FindControls<T>(WinFormsControl root) where T : WinFormsControl
|
||||||
@@ -713,13 +880,89 @@ namespace Lskj.Main.Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DevExpress 15.2 在触发普通 Paint 事件后还会继续绘制页签头,导致自定义
|
||||||
|
/// 矩形被覆盖。NativeWindow 在 WM_PAINT 完成后绘制,既保留原页签的命中
|
||||||
|
/// 测试、切换和关闭逻辑,又能保证最终显示的是 WPF 风格页签。
|
||||||
|
/// </summary>
|
||||||
|
private sealed class MainTabsNativeWindow : NativeWindow, IDisposable
|
||||||
|
{
|
||||||
|
private const int WmPaint = 0x000F;
|
||||||
|
private XtraTabControl _tabs;
|
||||||
|
private bool _drawing;
|
||||||
|
|
||||||
|
public void Attach(XtraTabControl tabs)
|
||||||
|
{
|
||||||
|
if (_tabs == tabs)
|
||||||
|
{
|
||||||
|
if (Handle == IntPtr.Zero && tabs != null && tabs.IsHandleCreated)
|
||||||
|
AssignHandle(tabs.Handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Detach();
|
||||||
|
_tabs = tabs;
|
||||||
|
if (_tabs == null) return;
|
||||||
|
_tabs.HandleCreated += Tabs_HandleCreated;
|
||||||
|
_tabs.HandleDestroyed += Tabs_HandleDestroyed;
|
||||||
|
if (_tabs.IsHandleCreated) AssignHandle(_tabs.Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Tabs_HandleCreated(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Handle == IntPtr.Zero && _tabs != null && _tabs.IsHandleCreated)
|
||||||
|
AssignHandle(_tabs.Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Tabs_HandleDestroyed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Handle != IntPtr.Zero) ReleaseHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void WndProc(ref Message m)
|
||||||
|
{
|
||||||
|
base.WndProc(ref m);
|
||||||
|
if (m.Msg != WmPaint || _drawing || _tabs == null ||
|
||||||
|
_tabs.IsDisposed || !_tabs.IsHandleCreated) return;
|
||||||
|
|
||||||
|
_drawing = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Graphics graphics = Graphics.FromHwnd(_tabs.Handle))
|
||||||
|
DrawMainTabs(_tabs, graphics);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_drawing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Detach()
|
||||||
|
{
|
||||||
|
if (_tabs != null)
|
||||||
|
{
|
||||||
|
_tabs.HandleCreated -= Tabs_HandleCreated;
|
||||||
|
_tabs.HandleDestroyed -= Tabs_HandleDestroyed;
|
||||||
|
}
|
||||||
|
if (Handle != IntPtr.Zero) ReleaseHandle();
|
||||||
|
_tabs = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class WpfMenuRenderer : ToolStripProfessionalRenderer
|
private sealed class WpfMenuRenderer : ToolStripProfessionalRenderer
|
||||||
{
|
{
|
||||||
private readonly Color _header;
|
private readonly Color _header;
|
||||||
|
private readonly Color _hover;
|
||||||
private readonly Func<ToolStripMenuItem> _activeMenuProvider;
|
private readonly Func<ToolStripMenuItem> _activeMenuProvider;
|
||||||
public WpfMenuRenderer(Color header, Func<ToolStripMenuItem> activeMenuProvider)
|
public WpfMenuRenderer(Color header, Func<ToolStripMenuItem> activeMenuProvider)
|
||||||
{
|
{
|
||||||
_header = header;
|
_header = header;
|
||||||
|
_hover = GetHoverColor(header);
|
||||||
_activeMenuProvider = activeMenuProvider;
|
_activeMenuProvider = activeMenuProvider;
|
||||||
}
|
}
|
||||||
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
|
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
|
||||||
@@ -755,7 +998,7 @@ namespace Lskj.Main.Control
|
|||||||
Rectangle r = new Rectangle(Point.Empty, item.Size);
|
Rectangle r = new Rectangle(Point.Empty, item.Size);
|
||||||
if (hover)
|
if (hover)
|
||||||
{
|
{
|
||||||
using (Brush brush = new SolidBrush(Color.FromArgb(42, 88, 164)))
|
using (Brush brush = new SolidBrush(_hover))
|
||||||
e.Graphics.FillRectangle(brush, r);
|
e.Graphics.FillRectangle(brush, r);
|
||||||
}
|
}
|
||||||
if (current)
|
if (current)
|
||||||
|
|||||||
+171
@@ -0,0 +1,171 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Lskj.Main
|
||||||
|
{
|
||||||
|
partial class FrmPersonalSetting
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components;
|
||||||
|
private Panel pnlHeader, pnlNavigation, pnlContent, pnlAppearance, pnlFonts;
|
||||||
|
private Button navAppearance, navFonts, btnSave, btnCancel, btnReset;
|
||||||
|
private TextBox txtTopColor, txtLeftColor, txtLeftSelectColor;
|
||||||
|
private Panel pnlTopPreview, pnlLeftPreview, pnlLeftSelectPreview;
|
||||||
|
private Button btnTopColor, btnLeftColor, btnLeftSelectColor;
|
||||||
|
private NumericUpDown numTopFont, numLeftFont;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && components != null) components.Dispose();
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep this method limited to straightforward assignments so the WinForms
|
||||||
|
// designer can parse it reliably.
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
components = new System.ComponentModel.Container();
|
||||||
|
Text = "个性化";
|
||||||
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
ClientSize = new Size(780, 582);
|
||||||
|
BackColor = Color.White;
|
||||||
|
Font = new Font("Microsoft YaHei", 9F);
|
||||||
|
|
||||||
|
pnlHeader = new Panel();
|
||||||
|
pnlNavigation = new Panel();
|
||||||
|
pnlContent = new Panel();
|
||||||
|
pnlAppearance = new Panel();
|
||||||
|
pnlFonts = new Panel();
|
||||||
|
pnlHeader.Dock = DockStyle.Top;
|
||||||
|
pnlHeader.Height = 36;
|
||||||
|
pnlHeader.BackColor = Color.FromArgb(7, 95, 166);
|
||||||
|
pnlNavigation.Dock = DockStyle.Left;
|
||||||
|
pnlNavigation.Width = 176;
|
||||||
|
pnlNavigation.BackColor = Color.FromArgb(247, 249, 252);
|
||||||
|
pnlNavigation.Padding = new Padding(8, 8, 8, 0);
|
||||||
|
pnlContent.Dock = DockStyle.Fill;
|
||||||
|
pnlContent.BackColor = Color.White;
|
||||||
|
pnlContent.Padding = new Padding(18, 0, 18, 0);
|
||||||
|
|
||||||
|
Controls.Add(pnlContent);
|
||||||
|
Controls.Add(pnlNavigation);
|
||||||
|
Controls.Add(pnlHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the remaining controls outside InitializeComponent. This is invoked
|
||||||
|
// by the form constructor for both runtime and Visual Studio design-time.
|
||||||
|
private void BuildDesignerControls()
|
||||||
|
{
|
||||||
|
Label title = new Label { Text = "● 个性化", ForeColor = Color.White, AutoSize = true, Location = new Point(12, 9), Font = new Font("Microsoft YaHei", 10F) };
|
||||||
|
Button close = new Button { Text = "×", FlatStyle = FlatStyle.Flat, ForeColor = Color.White, BackColor = Color.Transparent, Size = new Size(32, 30), Anchor = AnchorStyles.Top | AnchorStyles.Right, Location = new Point(740, 3) };
|
||||||
|
close.FlatAppearance.BorderSize = 0;
|
||||||
|
close.Click += delegate { Close(); };
|
||||||
|
pnlHeader.Controls.Add(title);
|
||||||
|
pnlHeader.Controls.Add(close);
|
||||||
|
|
||||||
|
navAppearance = MakeNavButton("外观", 8);
|
||||||
|
navFonts = MakeNavButton("字体与字号", 48);
|
||||||
|
navAppearance.Click += navAppearance_Click;
|
||||||
|
navFonts.Click += navFonts_Click;
|
||||||
|
pnlNavigation.Controls.Add(navFonts);
|
||||||
|
pnlNavigation.Controls.Add(navAppearance);
|
||||||
|
|
||||||
|
pnlAppearance = MakePage();
|
||||||
|
pnlFonts = MakePage();
|
||||||
|
pnlFonts.Visible = false;
|
||||||
|
pnlContent.Controls.Add(pnlFonts);
|
||||||
|
pnlContent.Controls.Add(pnlAppearance);
|
||||||
|
BuildAppearancePage();
|
||||||
|
BuildFontsPage();
|
||||||
|
|
||||||
|
Panel footer = new Panel { Dock = DockStyle.Bottom, Height = 48, BackColor = Color.White, BorderStyle = BorderStyle.FixedSingle };
|
||||||
|
btnReset = MakeFooterButton("恢复默认", 12);
|
||||||
|
btnCancel = MakeFooterButton("取消", 610);
|
||||||
|
btnSave = MakeFooterButton("保存", 690);
|
||||||
|
btnReset.Click += btnReset_Click;
|
||||||
|
btnCancel.Click += btnCancel_Click;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
footer.Controls.Add(btnReset);
|
||||||
|
footer.Controls.Add(btnCancel);
|
||||||
|
footer.Controls.Add(btnSave);
|
||||||
|
Controls.Add(footer);
|
||||||
|
ShowPage(pnlAppearance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button MakeNavButton(string text, int top)
|
||||||
|
{
|
||||||
|
return new Button { Text = text, TextAlign = ContentAlignment.MiddleLeft, Padding = new Padding(14, 0, 0, 0), FlatStyle = FlatStyle.Flat, ForeColor = Color.FromArgb(50, 70, 95), BackColor = Color.Transparent, Size = new Size(160, 36), Location = new Point(8, top) };
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button MakeFooterButton(string text, int left)
|
||||||
|
{
|
||||||
|
return new Button { Text = text, FlatStyle = FlatStyle.Flat, BackColor = Color.White, ForeColor = Color.FromArgb(65, 85, 110), Size = new Size(70, 30), Location = new Point(left, 8), Anchor = AnchorStyles.Right | AnchorStyles.Top };
|
||||||
|
}
|
||||||
|
|
||||||
|
private Panel MakePage() { return new Panel { Dock = DockStyle.Fill, BackColor = Color.White }; }
|
||||||
|
|
||||||
|
private Label MakeLabel(string text, int top)
|
||||||
|
{
|
||||||
|
return new Label { Text = text, AutoSize = true, Location = new Point(2, top + 7), ForeColor = Color.FromArgb(35, 48, 65), Font = new Font("Microsoft YaHei", 9F) };
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddRow(Panel page, Label label, System.Windows.Forms.Control editor, int top)
|
||||||
|
{
|
||||||
|
Panel row = new Panel { Height = 64, Width = 560, Location = new Point(0, top), Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right, BorderStyle = BorderStyle.FixedSingle, BackColor = Color.White };
|
||||||
|
label.Location = new Point(20, 22);
|
||||||
|
row.Controls.Add(label);
|
||||||
|
editor.Location = new Point(318, 16);
|
||||||
|
row.Controls.Add(editor);
|
||||||
|
page.Controls.Add(row);
|
||||||
|
row.BringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildAppearancePage()
|
||||||
|
{
|
||||||
|
Label heading = new Label { Text = "外观", Dock = DockStyle.Top, Height = 38, Padding = new Padding(2, 11, 0, 0), ForeColor = Color.FromArgb(45, 65, 90) };
|
||||||
|
pnlAppearance.Controls.Add(heading);
|
||||||
|
txtTopColor = MakeColorText(); pnlTopPreview = MakePreview(); btnTopColor = MakeChooseButton();
|
||||||
|
AddRow(pnlAppearance, MakeLabel("顶部菜单背景色", 0), MakeColorEditor(txtTopColor, pnlTopPreview, btnTopColor), 38);
|
||||||
|
btnTopColor.Click += btnTopColor_Click; txtTopColor.TextChanged += txtColor_TextChanged;
|
||||||
|
txtLeftColor = MakeColorText(); pnlLeftPreview = MakePreview(); btnLeftColor = MakeChooseButton();
|
||||||
|
AddRow(pnlAppearance, MakeLabel("左侧菜单背景色", 0), MakeColorEditor(txtLeftColor, pnlLeftPreview, btnLeftColor), 102);
|
||||||
|
btnLeftColor.Click += btnLeftColor_Click; txtLeftColor.TextChanged += txtColor_TextChanged;
|
||||||
|
txtLeftSelectColor = MakeColorText(); pnlLeftSelectPreview = MakePreview(); btnLeftSelectColor = MakeChooseButton();
|
||||||
|
AddRow(pnlAppearance, MakeLabel("左侧菜单选中背景色", 0), MakeColorEditor(txtLeftSelectColor, pnlLeftSelectPreview, btnLeftSelectColor), 166);
|
||||||
|
btnLeftSelectColor.Click += btnLeftSelectColor_Click; txtLeftSelectColor.TextChanged += txtColor_TextChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildFontsPage()
|
||||||
|
{
|
||||||
|
Label heading = new Label { Text = "字体与字号", Dock = DockStyle.Top, Height = 38, Padding = new Padding(2, 11, 0, 0), ForeColor = Color.FromArgb(45, 65, 90) };
|
||||||
|
pnlFonts.Controls.Add(heading);
|
||||||
|
numTopFont = MakeNumber(); numLeftFont = MakeNumber();
|
||||||
|
AddRow(pnlFonts, MakeLabel("顶部菜单字号", 0), numTopFont, 38);
|
||||||
|
AddRow(pnlFonts, MakeLabel("左侧菜单字号", 0), numLeftFont, 102);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextBox MakeColorText() { return new TextBox { Width = 130, Height = 24, BorderStyle = BorderStyle.FixedSingle }; }
|
||||||
|
private Panel MakePreview() { return new Panel { Width = 24, Height = 22, BorderStyle = BorderStyle.FixedSingle }; }
|
||||||
|
private Button MakeChooseButton() { return new Button { Text = "选择", Width = 52, Height = 24, FlatStyle = FlatStyle.Flat }; }
|
||||||
|
|
||||||
|
private Panel MakeColorEditor(TextBox text, Panel preview, Button choose)
|
||||||
|
{
|
||||||
|
Panel p = new Panel { Width = 260, Height = 28 };
|
||||||
|
text.Location = new Point(0, 1); preview.Location = new Point(136, 1); choose.Location = new Point(166, 0);
|
||||||
|
p.Controls.Add(text); p.Controls.Add(preview); p.Controls.Add(choose); return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NumericUpDown MakeNumber() { return new NumericUpDown { Width = 220, Minimum = 8, Maximum = 24, Value = 12, BorderStyle = BorderStyle.FixedSingle }; }
|
||||||
|
|
||||||
|
private void ShowPage(System.Windows.Forms.Control page)
|
||||||
|
{
|
||||||
|
if (pnlAppearance == null || pnlFonts == null) return;
|
||||||
|
pnlAppearance.Visible = page == pnlAppearance;
|
||||||
|
pnlFonts.Visible = page == pnlFonts;
|
||||||
|
if (navAppearance != null) navAppearance.BackColor = pnlAppearance.Visible ? Color.FromArgb(229, 239, 250) : Color.Transparent;
|
||||||
|
if (navFonts != null) navFonts.BackColor = pnlFonts.Visible ? Color.FromArgb(229, 239, 250) : Color.Transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
using Lskj.Control;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Lskj.Main
|
||||||
|
{
|
||||||
|
public partial class FrmPersonalSetting : BaseForm
|
||||||
|
{
|
||||||
|
private MainAppearanceSettings _settings;
|
||||||
|
|
||||||
|
public FrmPersonalSetting()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
BuildDesignerControls();
|
||||||
|
// 设计器只需要静态控件,不访问本地配置文件或运行时状态。
|
||||||
|
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return;
|
||||||
|
_settings = MainAppearanceSettingsStore.Load();
|
||||||
|
LoadSettingsToControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSettingsToControls()
|
||||||
|
{
|
||||||
|
txtTopColor.Text = _settings.TopMenuBackground;
|
||||||
|
txtLeftColor.Text = _settings.SidebarBackground;
|
||||||
|
txtLeftSelectColor.Text = _settings.SidebarSelectedBackground;
|
||||||
|
numTopFont.Value = Clamp(_settings.TopMenuFontSize, numTopFont.Minimum, numTopFont.Maximum);
|
||||||
|
numLeftFont.Value = Clamp(_settings.LeftMenuFontSize, numLeftFont.Minimum, numLeftFont.Maximum);
|
||||||
|
// An empty value means "use the program default". Keep the editor
|
||||||
|
// visually empty while MainPanelControlEx2 still uses its fallback.
|
||||||
|
if (!_settings.TopMenuFontConfigured) numTopFont.Text = string.Empty;
|
||||||
|
if (!_settings.LeftMenuFontConfigured) numLeftFont.Text = string.Empty;
|
||||||
|
UpdateColorPreview(txtTopColor, pnlTopPreview);
|
||||||
|
UpdateColorPreview(txtLeftColor, pnlLeftPreview);
|
||||||
|
UpdateColorPreview(txtLeftSelectColor, pnlLeftSelectPreview);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveSettings()
|
||||||
|
{
|
||||||
|
int ignoredTopFont;
|
||||||
|
int ignoredLeftFont;
|
||||||
|
MainAppearanceSettingsStore.Save(new MainAppearanceSettings
|
||||||
|
{
|
||||||
|
TopMenuBackground = MainAppearanceSettingsStore.NormalizeColor(txtTopColor.Text, _settings.TopMenuBackground),
|
||||||
|
SidebarBackground = MainAppearanceSettingsStore.NormalizeColor(txtLeftColor.Text, _settings.SidebarBackground),
|
||||||
|
SidebarSelectedBackground = MainAppearanceSettingsStore.NormalizeColor(txtLeftSelectColor.Text, _settings.SidebarSelectedBackground),
|
||||||
|
TopMenuFontSize = ParseFontEditorValue(numTopFont, MainAppearanceSettingsStore.DefaultTopMenuFontSize),
|
||||||
|
LeftMenuFontSize = ParseFontEditorValue(numLeftFont, MainAppearanceSettingsStore.DefaultLeftMenuFontSize),
|
||||||
|
TopMenuFontConfigured = TryParseFontEditorValue(numTopFont, out ignoredTopFont),
|
||||||
|
LeftMenuFontConfigured = TryParseFontEditorValue(numLeftFont, out ignoredLeftFont)
|
||||||
|
});
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChooseColor(TextBox textBox, Panel preview)
|
||||||
|
{
|
||||||
|
Color current = MainAppearanceSettingsStore.ParseColor(textBox.Text, Color.White);
|
||||||
|
using (ColorDialog dialog = new ColorDialog { Color = current, FullOpen = true })
|
||||||
|
{
|
||||||
|
if (dialog.ShowDialog(this) != DialogResult.OK) return;
|
||||||
|
textBox.Text = MainAppearanceSettingsStore.FormatColor(dialog.Color);
|
||||||
|
UpdateColorPreview(textBox, preview);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateColorPreview(TextBox textBox, Panel preview)
|
||||||
|
{
|
||||||
|
if (preview != null) preview.BackColor = MainAppearanceSettingsStore.ParseColor(textBox.Text, Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static decimal Clamp(int value, decimal min, decimal max)
|
||||||
|
{
|
||||||
|
return Math.Min(max, Math.Max(min, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseFontEditorValue(NumericUpDown editor, out int value)
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
int parsed;
|
||||||
|
if (!int.TryParse((editor == null ? string.Empty : editor.Text ?? string.Empty).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out parsed)) return false;
|
||||||
|
if (parsed < MainAppearanceSettingsStore.MinimumFontSize || parsed > MainAppearanceSettingsStore.MaximumFontSize) return false;
|
||||||
|
value = parsed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ParseFontEditorValue(NumericUpDown editor, int fallback)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
return TryParseFontEditorValue(editor, out value) ? value : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtColor_TextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (sender == txtTopColor) UpdateColorPreview(txtTopColor, pnlTopPreview);
|
||||||
|
else if (sender == txtLeftColor) UpdateColorPreview(txtLeftColor, pnlLeftPreview);
|
||||||
|
else if (sender == txtLeftSelectColor) UpdateColorPreview(txtLeftSelectColor, pnlLeftSelectPreview);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnTopColor_Click(object sender, EventArgs e) { ChooseColor(txtTopColor, pnlTopPreview); }
|
||||||
|
private void btnLeftColor_Click(object sender, EventArgs e) { ChooseColor(txtLeftColor, pnlLeftPreview); }
|
||||||
|
private void btnLeftSelectColor_Click(object sender, EventArgs e) { ChooseColor(txtLeftSelectColor, pnlLeftSelectPreview); }
|
||||||
|
private void btnSave_Click(object sender, EventArgs e) { SaveSettings(); }
|
||||||
|
private void btnCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); }
|
||||||
|
private void btnReset_Click(object sender, EventArgs e) { _settings = MainAppearanceSettingsStore.Defaults(); LoadSettingsToControls(); }
|
||||||
|
private void navAppearance_Click(object sender, EventArgs e) { ShowPage(pnlAppearance); }
|
||||||
|
private void navFonts_Click(object sender, EventArgs e) { ShowPage(pnlFonts); }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class MainAppearanceSettings
|
||||||
|
{
|
||||||
|
public string TopMenuBackground;
|
||||||
|
public string SidebarBackground;
|
||||||
|
public string SidebarSelectedBackground;
|
||||||
|
public int TopMenuFontSize;
|
||||||
|
public int LeftMenuFontSize;
|
||||||
|
public bool TopMenuFontConfigured;
|
||||||
|
public bool LeftMenuFontConfigured;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class MainAppearanceSettingsStore
|
||||||
|
{
|
||||||
|
internal const int DefaultTopMenuFontSize = 9;
|
||||||
|
internal const int DefaultLeftMenuFontSize = 12;
|
||||||
|
internal const int MinimumFontSize = 8;
|
||||||
|
internal const int MaximumFontSize = 24;
|
||||||
|
// WinForms uses a separate file so changing the WPF shell settings does not
|
||||||
|
// unexpectedly alter the transitional WinForms main panel.
|
||||||
|
private const string FileName = "WinFromShellAppearance.ini";
|
||||||
|
private const string TopColorKey = "TopMenuBackground=";
|
||||||
|
private const string LeftColorKey = "SidebarBackground=";
|
||||||
|
private const string LeftSelectedColorKey = "SidebarSelectedBackground=";
|
||||||
|
private const string TopFontKey = "TopMenuFontSize=";
|
||||||
|
private const string LeftFontKey = "LeftMenuFontSize=";
|
||||||
|
|
||||||
|
public static MainAppearanceSettings Defaults()
|
||||||
|
{
|
||||||
|
return new MainAppearanceSettings
|
||||||
|
{
|
||||||
|
TopMenuBackground = "#1F4B99",
|
||||||
|
SidebarBackground = "#272D51",
|
||||||
|
SidebarSelectedBackground = "#348ED8",
|
||||||
|
TopMenuFontSize = DefaultTopMenuFontSize,
|
||||||
|
LeftMenuFontSize = DefaultLeftMenuFontSize,
|
||||||
|
TopMenuFontConfigured = false,
|
||||||
|
LeftMenuFontConfigured = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MainAppearanceSettings Load()
|
||||||
|
{
|
||||||
|
MainAppearanceSettings result = Defaults();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string path = GetPath();
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
// Create the WinForms-specific file on first run so the active
|
||||||
|
// values are visible and editable from the Debug\Config folder.
|
||||||
|
Save(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
foreach (string raw in File.ReadAllLines(path))
|
||||||
|
{
|
||||||
|
string line = (raw ?? string.Empty).Trim();
|
||||||
|
if (line.StartsWith(TopColorKey, StringComparison.OrdinalIgnoreCase)) result.TopMenuBackground = NormalizeColor(line.Substring(TopColorKey.Length), result.TopMenuBackground);
|
||||||
|
else if (line.StartsWith(LeftColorKey, StringComparison.OrdinalIgnoreCase)) result.SidebarBackground = NormalizeColor(line.Substring(LeftColorKey.Length), result.SidebarBackground);
|
||||||
|
else if (line.StartsWith(LeftSelectedColorKey, StringComparison.OrdinalIgnoreCase)) result.SidebarSelectedBackground = NormalizeColor(line.Substring(LeftSelectedColorKey.Length), result.SidebarSelectedBackground);
|
||||||
|
else if (line.StartsWith(TopFontKey, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
if (TryParseFont(line.Substring(TopFontKey.Length), out value)) { result.TopMenuFontSize = value; result.TopMenuFontConfigured = true; }
|
||||||
|
}
|
||||||
|
else if (line.StartsWith(LeftFontKey, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
if (TryParseFont(line.Substring(LeftFontKey.Length), out value)) { result.LeftMenuFontSize = value; result.LeftMenuFontConfigured = true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception) { }
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Save(MainAppearanceSettings settings)
|
||||||
|
{
|
||||||
|
if (settings == null) return;
|
||||||
|
string path = GetPath();
|
||||||
|
string[] oldLines = new string[0];
|
||||||
|
try { if (File.Exists(path)) oldLines = File.ReadAllLines(path); } catch (Exception) { }
|
||||||
|
string[] replacements =
|
||||||
|
{
|
||||||
|
TopColorKey + NormalizeColor(settings.TopMenuBackground, "#1F4B99"),
|
||||||
|
LeftColorKey + NormalizeColor(settings.SidebarBackground, "#272D51"),
|
||||||
|
LeftSelectedColorKey + NormalizeColor(settings.SidebarSelectedBackground, "#348ED8"),
|
||||||
|
TopFontKey + (settings.TopMenuFontConfigured ? settings.TopMenuFontSize.ToString(CultureInfo.InvariantCulture) : string.Empty),
|
||||||
|
LeftFontKey + (settings.LeftMenuFontConfigured ? settings.LeftMenuFontSize.ToString(CultureInfo.InvariantCulture) : string.Empty)
|
||||||
|
};
|
||||||
|
string[] keys = { TopColorKey, LeftColorKey, LeftSelectedColorKey, TopFontKey, LeftFontKey };
|
||||||
|
var output = oldLines.ToList();
|
||||||
|
for (int i = 0; i < keys.Length; i++)
|
||||||
|
{
|
||||||
|
int index = output.FindIndex(x => (x ?? string.Empty).Trim().StartsWith(keys[i], StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (index >= 0) output[index] = replacements[i]; else output.Add(replacements[i]);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string dir = Path.GetDirectoryName(path);
|
||||||
|
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
||||||
|
File.WriteAllLines(path, output.ToArray());
|
||||||
|
}
|
||||||
|
catch (Exception) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string NormalizeColor(string value, string fallback)
|
||||||
|
{
|
||||||
|
return FormatColor(ParseColor(value, ParseColor(fallback, Color.Black)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color ParseColor(string value, Color fallback)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value)) return fallback;
|
||||||
|
string text = value.Trim();
|
||||||
|
if (!text.StartsWith("#", StringComparison.Ordinal) || text.Length != 7) return fallback;
|
||||||
|
byte r, g, b;
|
||||||
|
if (!byte.TryParse(text.Substring(1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out r) || !byte.TryParse(text.Substring(3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out g) || !byte.TryParse(text.Substring(5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out b)) return fallback;
|
||||||
|
return Color.FromArgb(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FormatColor(Color color)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.InvariantCulture, "#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseFont(string value, out int result)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
return int.TryParse((value ?? string.Empty).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result)
|
||||||
|
&& result >= MinimumFontSize && result <= MaximumFontSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetPath()
|
||||||
|
{
|
||||||
|
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -246,6 +246,12 @@
|
|||||||
<Compile Include="FrmPassword.Designer.cs">
|
<Compile Include="FrmPassword.Designer.cs">
|
||||||
<DependentUpon>FrmPassword.cs</DependentUpon>
|
<DependentUpon>FrmPassword.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="FrmPersonalSetting.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="FrmPersonalSetting.Designer.cs">
|
||||||
|
<DependentUpon>FrmPersonalSetting.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="FrmSkins.cs">
|
<Compile Include="FrmSkins.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
Reference in New Issue
Block a user