diff --git a/插件库/Lskj.Business/Impl/SystemInfo.cs b/插件库/Lskj.Business/Impl/SystemInfo.cs index f506ce9..856e57b 100644 --- a/插件库/Lskj.Business/Impl/SystemInfo.cs +++ b/插件库/Lskj.Business/Impl/SystemInfo.cs @@ -342,7 +342,13 @@ 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); + if (Instance.NewMain) + { + Instance.MainLeftShowMode = "1"; + Instance.DefaultMainTag = 4; + } } /// /// 高拍仪AccessKey @@ -1184,5 +1190,9 @@ namespace Lskj.Business /// 导入成功不会提示,直接关闭导入框(失败时还是会提示) /// public bool SuppressImportSuccessTip; + /// + /// 新版界面(读取 P_SystemTab.NewMain;true 时加载 MainPanelControlEx2,默认使用旧界面) + /// + public bool NewMain; } } diff --git a/插件库/Lskj.Control/MultiModelLookUp/FrmModelLookUp2.cs b/插件库/Lskj.Control/MultiModelLookUp/FrmModelLookUp2.cs index 1fc8b82..a560725 100644 --- a/插件库/Lskj.Control/MultiModelLookUp/FrmModelLookUp2.cs +++ b/插件库/Lskj.Control/MultiModelLookUp/FrmModelLookUp2.cs @@ -192,8 +192,12 @@ namespace Lskj.Control.MultiModelLookUp this.gcDetail.GridView.OptionsSelection.EnableAppearanceFocusedCell = false; this.Resize += new System.EventHandler(maximization); this.splitMain_Right.SplitterMoved += new EventHandler(PositionChange); - this.gcDetail.GridView.OptionsView.ColumnAutoWidth = true; - this.gcMain.GridView.OptionsView.ColumnAutoWidth = true; + //this.gcDetail.GridView.OptionsView.ColumnAutoWidth = true; + //this.gcMain.GridView.OptionsView.ColumnAutoWidth = true; + this.gcDetail.GridView.OptionsView.ColumnAutoWidth = false; + this.gcDetail.GridView.HorzScrollVisibility = DevExpress.XtraGrid.Views.Base.ScrollVisibility.Auto; + this.gcMain.GridView.OptionsView.ColumnAutoWidth = false; + this.gcMain.GridView.HorzScrollVisibility =DevExpress.XtraGrid.Views.Base.ScrollVisibility.Auto; } //关联模块号;是否为单选模式 @@ -243,8 +247,12 @@ namespace Lskj.Control.MultiModelLookUp this.SourceSQL = this.SysModel.MenuSql; this.gcDetail.GridView.OptionsSelection.EnableAppearanceFocusedCell = false; - this.gcDetail.GridView.OptionsView.ColumnAutoWidth = true; - this.gcMain.GridView.OptionsView.ColumnAutoWidth = true; + //this.gcDetail.GridView.OptionsView.ColumnAutoWidth = true; + //this.gcMain.GridView.OptionsView.ColumnAutoWidth = true; + this.gcDetail.GridView.OptionsView.ColumnAutoWidth = false; + this.gcDetail.GridView.HorzScrollVisibility =DevExpress.XtraGrid.Views.Base.ScrollVisibility.Auto; + this.gcMain.GridView.OptionsView.ColumnAutoWidth = false; + this.gcMain.GridView.HorzScrollVisibility =DevExpress.XtraGrid.Views.Base.ScrollVisibility.Auto; } diff --git a/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs b/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs new file mode 100644 index 0000000..c451c01 --- /dev/null +++ b/插件库/Lskj.Main/Control/MainPanelControlEx2.Designer.cs @@ -0,0 +1,584 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevExpress.XtraTab; +using DevExpress.XtraTreeList; +using Lskj.Business; +using Lskj.Model; +using WinFormsControl = System.Windows.Forms.Control; + +namespace Lskj.Main.Control +{ + partial class MainPanelControlEx2 + { + private static readonly Color HeaderColor = Color.FromArgb(31, 75, 153); + private static readonly Color SidebarColor = Color.FromArgb(39, 45, 81); + private static readonly Color SidebarSelectedColor = Color.FromArgb(52, 142, 216); + private static readonly Color WorkspaceColor = Color.FromArgb(247, 249, 252); + private static readonly Color ShortcutBorderColor = Color.FromArgb(221, 227, 234); + private System.ComponentModel.IContainer components = null; + private MainPanelControlEx _legacyPanel; + + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) components.Dispose(); + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + private void InitializeComponent() + { + this._legacyPanel = new Lskj.Main.Control.MainPanelControlEx(); + this.SuspendLayout(); + // + // _legacyPanel + // + this._legacyPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this._legacyPanel.Location = new System.Drawing.Point(0, 0); + this._legacyPanel.Name = "_legacyPanel"; + this._legacyPanel.Size = new System.Drawing.Size(1275, 696); + this._legacyPanel.TabIndex = 0; + // + // MainPanelControlEx2 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this._legacyPanel); + this.Name = "MainPanelControlEx2"; + this.Size = new System.Drawing.Size(1275, 696); + this.ResumeLayout(false); + + } + #endregion + + #region 新版主界面外观 + private void ApplyWpfShellStyle() + { + 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 (headerLeft != null) + { + headerLeft.Width = 176; + headerLeft.BackColor = HeaderColor; + headerLeft.BackgroundImage = null; + AddBrandVisual(headerLeft); + } + if (headerCenter != null) { headerCenter.BackColor = HeaderColor; headerCenter.Padding = new Padding(0, 9, 0, 0); } + // 右上角继续使用旧版控件、按钮和位置,仅统一顶部背景色。 + if (headerRight != null) { headerRight.BackColor = HeaderColor; headerRight.BackgroundImage = null; } + // 旧版 Logo 与菜单之间有 19px 的装饰分隔面板;WPF 顶部栏是连续布局, + // 保留该控件会在两块蓝色之间形成突兀的深色竖条。 + if (headerSeparator != null) + { + headerSeparator.Width = 0; + headerSeparator.BackColor = HeaderColor; + headerSeparator.BackgroundImage = null; + } + StyleSearchControls(); + if (topMenu != null) StyleTopNavigation(topMenu); + StyleMainTabs(); + StyleSidebar(); + StyleWorkspaceAndShortcuts(); + RememberStyledNavigation(); + } + + private void AddBrandVisual(WinFormsControl host) + { + if (host.Controls.Find("wpfBrandVisual", false).Length > 0) return; + PictureBox logo = new PictureBox + { + Name = "wpfBrandVisual", BackColor = Color.Transparent, + Size = new Size(150, 32), Location = new Point(12, 9), + SizeMode = PictureBoxSizeMode.Zoom + }; + Image image = LoadWpfHeaderLogo(); + if (image != null) + { + logo.Image = image; + host.Controls.Add(logo); + logo.BringToFront(); + } + WinFormsControl oldTitle = host.Controls.Find("lblSubTitle", true).FirstOrDefault(); + if (oldTitle != null) oldTitle.Visible = false; + } + + private static Image LoadWpfHeaderLogo() + { + // 客户部署时只从程序目录下的 Images\Main 查找 Logo; + // 文件不存在则不显示图片,不再回退到开发机或 SVG 资源。 + string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images", "Main", "logoNew.png"); + try + { + if (!File.Exists(path)) return null; + // 克隆后释放文件句柄,避免程序运行期间锁定更新包中的图片。 + using (Image source = Image.FromFile(path)) return new Bitmap(source); + } + catch (Exception) + { + return null; + } + } + + private void StyleMainTabs() + { + XtraTabControl tabs = FindControl("tabMain"); + if (tabs == null) return; + + // 旧版 DevExpress 皮肤会把相邻页签绘成深浅不一的灰块, + // 在新版蓝色顶部栏下显得突兀;统一为 WPF 主界面的浅灰页签带, + // 当前页签保持白色,边界与左侧导航自然衔接。 + Color tabStrip = Color.FromArgb(245, 247, 251); + Color tabHover = Color.FromArgb(232, 239, 249); + Color tabBorder = Color.FromArgb(214, 222, 233); + tabs.PaintStyleName = "Flat"; + tabs.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Top; + tabs.HeaderAutoFill = DevExpress.Utils.DefaultBoolean.False; + tabs.TabPageWidth = 0; + tabs.BackColor = tabStrip; + tabs.Appearance.BackColor = tabStrip; + tabs.Appearance.Options.UseBackColor = true; + ConfigureTabAppearance(tabs.AppearancePage.Header, Color.White, Color.FromArgb(74, 86, 105), tabBorder); + ConfigureTabAppearance(tabs.AppearancePage.HeaderActive, Color.White, Color.FromArgb(31, 119, 201), tabBorder); + ConfigureTabAppearance(tabs.AppearancePage.HeaderHotTracked, tabHover, Color.FromArgb(31, 119, 201), tabBorder); + ConfigureTabAppearance(tabs.AppearancePage.HeaderDisabled, tabStrip, Color.FromArgb(160, 169, 182), tabBorder); + tabs.AppearancePage.Header.Font = new Font("微软雅黑", 9F); + tabs.AppearancePage.HeaderActive.Font = tabs.AppearancePage.Header.Font; + tabs.AppearancePage.HeaderHotTracked.Font = tabs.AppearancePage.Header.Font; + tabs.AppearancePage.HeaderDisabled.Font = tabs.AppearancePage.Header.Font; + + // 功能导航页签要与左侧 176px 目录栏严格对齐。DevExpress 旧版 + // 页签宽度按文本自适应,因此用不可见的全角空格补足首个页签宽度, + // 其它页签仍保持按内容自适应,并通过边框清晰分隔。 + XtraTabPage first = tabs.TabPages.Cast().FirstOrDefault(p => p.Name == "xtpFirst"); + if (first != null) first.Text = "功能导航" + new string('\u3000', 10); + } + + private static void ConfigureTabAppearance(DevExpress.Utils.AppearanceObject appearance, Color backColor, Color foreColor, Color borderColor) + { + appearance.BackColor = backColor; + appearance.ForeColor = foreColor; + appearance.BorderColor = borderColor; + appearance.Options.UseBackColor = true; + appearance.Options.UseForeColor = true; + appearance.Options.UseBorderColor = true; + } + + private void StyleSearchControls() + { + // 旧版搜索框和按钮原本位于 y=27、高度 25/26,顶部栏改为 50px 后 + // 底部会被裁掉约 2~3px。仅上移 2px 并缩短 1~2px,保留足够的 + // 输入高度和按钮点击区域,避免控件显得过小。 + WinFormsControl searchBox = FindControl("lueUserName"); + if (searchBox != null) + { + searchBox.Top = 25; + searchBox.Height = 24; + } + PictureBox searchButton = FindControl("pic_search"); + if (searchButton != null) + { + searchButton.Top = 25; + searchButton.Height = 24; + } + } + + private void StyleTopNavigation(MenuStrip menu) + { + menu.Renderer = new WpfMenuRenderer(HeaderColor, () => + { + // 每次绘制都重新读取当前导航,支持旧版双击或其它入口切换目录。 + return FindCurrentTopMenu(menu) ?? _selectedTopMenu; + }); + menu.BackColor = HeaderColor; + menu.ForeColor = Color.FromArgb(242, 246, 255); + menu.Font = new Font("微软雅黑", 10F); + menu.Dock = DockStyle.Fill; + menu.Location = Point.Empty; + menu.Padding = new Padding(4, 0, 4, 0); + menu.AutoSize = false; + menu.Height = 32; + foreach (ToolStripMenuItem item in menu.Items.OfType()) + { + item.BackColor = Color.Transparent; + item.ForeColor = Color.FromArgb(242, 246, 255); + item.Font = menu.Font; + item.Padding = new Padding(8, 0, 8, 0); + item.Margin = Padding.Empty; + item.AutoSize = true; + item.Click -= TopMenuItem_Click; + item.Click += TopMenuItem_Click; + item.DropDownOpened -= TopMenuDropDownOpened; + item.DropDownOpened += TopMenuDropDownOpened; + item.DropDownClosed -= TopMenuDropDownClosed; + item.DropDownClosed += TopMenuDropDownClosed; + HookDropDownClicks(item); + } + // 当前功能导航是唯一权威状态。旧版在双击切换目录时会更新 + // ERPInfo.Instance.SubSysName;这里每次重新套用样式都优先按该值查找, + // 避免上一次点击留下的菜单项一直保持高亮。 + ToolStripMenuItem current = FindCurrentTopMenu(menu); + if (current == null) + current = _selectedTopMenu; + if (current == null || !menu.Items.Contains(current)) + current = null; + if (current == null) + current = menu.Items.OfType().FirstOrDefault(); + SelectTopMenu(current); + } + + private void HookDropDownClicks(ToolStripMenuItem root) + { + foreach (ToolStripMenuItem child in root.DropDownItems.OfType()) + { + child.Click -= LegacyDropDownItem_Click; + child.Click += LegacyDropDownItem_Click; + HookDropDownClicks(child); + } + } + + private void LegacyDropDownItem_Click(object sender, EventArgs e) + { + ToolStripMenuItem item = sender as ToolStripMenuItem; + if (item == null) return; + // 普通二级模块点击不会改变当前功能导航,不要因此重做右侧布局。 + if (!IsNavigationChangedSinceLastStyle()) return; + _selectedTopMenu = null; + RequestApplyWpfShellStyle(); + } + + private void TopMenuDropDownOpened(object sender, EventArgs e) + { + // 下拉菜单展开及二级目录移动期间,旧版会触发父容器重绘; + // 暂停右侧快捷通道的 WM_PAINT,避免看到中间清空状态。 + SetShortcutRedraw(false); + } + + private void TopMenuDropDownClosed(object sender, EventArgs e) + { + // 若目录切换已经排队,保持暂停到统一样式刷新完成,避免先显示中间状态。 + if (_styleUpdatePending) return; + SetShortcutRedraw(true); + } + + private void SetShortcutRedraw(bool enabled) + { + _shortcutRedrawSuppressed = !enabled; + Panel right = FindControl("pl_center_main_right"); + Panel container = FindControl("pl_center_main_right_container"); + SendRedrawMessage(right, enabled); + if (container != right) SendRedrawMessage(container, enabled); + if (enabled && !_styleUpdatePending) + { + if (right != null) right.Invalidate(true); + if (container != null) container.Invalidate(true); + } + } + + private static void SendRedrawMessage(WinFormsControl control, bool enabled) + { + if (control == null || !control.IsHandleCreated) return; + SendMessage(control.Handle, 0x000B, new IntPtr(enabled ? 1 : 0), IntPtr.Zero); + } + + [DllImport("user32.dll")] + private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); + + private static ToolStripMenuItem FindCurrentTopMenu(MenuStrip menu) + { + // 设计器中旧控件尚未加载业务数据,不能触发 ERPInfo 的运行时初始化。 + if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return null; + string currentName = (ERPInfo.Instance.SubSysName ?? string.Empty).Trim(); + string currentId = (ERPInfo.Instance.SubSysId ?? string.Empty).Trim(); + if (string.IsNullOrWhiteSpace(currentName) && string.IsNullOrWhiteSpace(currentId)) return null; + foreach (ToolStripMenuItem item in menu.Items.OfType()) + { + if (MenuItemMatchesCurrent(item, currentName, currentId)) return item; + // “更多”中的目录仍属于顶部一级导航,命中子项时返回其顶层父项, + // 这样当前目录无论是否被收进下拉框都能保持顶部高亮。 + foreach (ToolStripMenuItem child in item.DropDownItems.OfType()) + { + if (MenuItemTreeMatchesCurrent(child, currentName, currentId)) return item; + } + } + return null; + } + + private static bool MenuItemTreeMatchesCurrent(ToolStripMenuItem item, string currentName, string currentId) + { + if (MenuItemMatchesCurrent(item, currentName, currentId)) return true; + foreach (ToolStripMenuItem child in item.DropDownItems.OfType()) + if (MenuItemTreeMatchesCurrent(child, currentName, currentId)) return true; + return false; + } + + private static bool MenuItemMatchesCurrent(ToolStripMenuItem item, string currentName, string currentId) + { + if (!string.IsNullOrWhiteSpace(currentName) + && string.Equals((item.Text ?? string.Empty).Trim(), currentName, StringComparison.OrdinalIgnoreCase)) + return true; + DataRow row = item.Tag as DataRow; + string itemId = row != null && row.Table.Columns.Contains("subsysid") + ? row["subsysid"] + "" + : item.Tag + ""; + return !string.IsNullOrWhiteSpace(currentId) + && string.Equals(itemId, currentId, StringComparison.OrdinalIgnoreCase); + } + + private void SelectTopMenu(ToolStripMenuItem item) + { + if (item == null) return; + _selectedTopMenu = item; + MenuStrip menu = FindControl("menuMain"); + if (menu == null) return; + foreach (ToolStripMenuItem top in menu.Items.OfType()) + { + top.ForeColor = top == item ? Color.FromArgb(255, 214, 102) : Color.FromArgb(242, 246, 255); + top.Invalidate(); + } + } + + private void ResetBrandArea() + { + Panel brandArea = FindControl("pl_top_left"); + if (brandArea != null) brandArea.Width = 176; + WinFormsControl oldTitle = FindControl("lblSubTitle"); + if (oldTitle != null) oldTitle.Visible = false; + } + + private void StyleSidebar() + { + Panel sidebar = FindControl("pl_center_left"); + if (sidebar == null) return; + // 新版侧栏对应旧程序的 MainLeftShowMode=1(分组树菜单)配置。 + bool useGroupedSidebar = IsGroupedSidebarMode(); + 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.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.Options.UseBackColor = true; tree.Appearance.FocusedRow.Options.UseForeColor = true; + 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.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.TextAlign = ContentAlignment.MiddleLeft; button.Padding = new Padding(20, 0, 12, 0); + button.Click -= SidebarButton_Click; + button.Click += SidebarButton_Click; + } + } + + private void SidebarButton_Click(object sender, EventArgs e) + { + Button selected = sender as Button; + if (selected == null) return; + Panel sidebar = FindControl("pl_center_left"); + foreach (Button button in FindControls