ToolStripManager 不会按预期将我的 Toolstrip 恢复到以前的位置。我创建了一个非常简单的应用程序来演示。 I 在 ToolStrip 容器中包含 4 个可移动的 Toolstrip。我移动工具条,将它们从上到下排列为 4-3-2-1(图 A)。然后关闭应用程序。当我重新打开它时,它们的顺序如图 B 所示。
这是简单的代码。我已验证 LoadSettings 和 SaveSettings 方法调用中使用的 Key 是相同的字符串。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ZT2
{
public partial class Form1 : Form
{
string keyName = "abc";
public Form1()
{
InitializeComponent();
keyName = Application.ProductName + this.Name + "xyz";
ToolStripManager.LoadSettings(this, keyName);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
ToolStripManager.SaveSettings(this, keyName);
}
}
}
Visual Studio 2010 - C# .Net 4 客户简介
通过以下方式保存表单关闭设置:
ToolStripManager.SaveSettings(this);
通过以下方式加载表单加载中的设置:
ToolStripManager.LoadSettings(this);
ToolStripContainer 的一个问题是您不能只设置包含 ToolStrip 的位置,因为容器总是检查容器中的其他 ToolStrip。
如果您在设计时没有将 ToolStrips 放入容器中,它可以正常工作。 您只需要一个函数来初始化它们一次。
另一种可能性是在调用 ToolStripManager.LoadSettings 函数之前将每个 Toolstrip 的父属性设置为 null
以防万一其他人最终陷入 ToolStripManager 地狱,这是我的解决方案。基本上,它完全使用 ToolStripContainer 和 ToolStripManager 进行导航,并通过用户设置和继承 ToolStripPanel(可通过 VS Designer 放置)的自定义控件来保留 ToolStrip 状态(位置和可见性)。这还会保留多个 ToolStripPanel,其中在面板之间拖动 ToolStrip。注意:它不执行 ToolStripManager 的所有其他功能,例如保留 ToolStrip 控件的顺序。
/// <summary>
/// Persists ToolStips via User Setting: ToolStripPanelItemLocations (you will need to create this)
/// Settings delimiter convention:
/// ToolStripPanelName|ToolStripName:LocationX,LocationY-Visible;ToolStripName:LocationX,LocationY-Visible
/// </summary>
[DesignerCategory("Code")]
[Browsable(true)]
public class ToolStripPanel : System.Windows.Forms.ToolStripPanel
{
public override Color BackColor { get; set; }
[DisplayName("Auto Arrange"), Description("Left justifies all toolstrips")]
public bool AutoArrange { get; set; } = false;
protected override void OnHandleCreated(EventArgs e)
{
// Load Toolstrips
LoadToolstripParameters();
base.OnHandleCreated(e);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// overrides default background draw which has some odd behaivours (e.g. lightening the set bg color)
e.Graphics.FillRectangle(new SolidBrush(BackColor), e.ClipRectangle);
}
protected override void Dispose(bool disposing)
{
// Persist toolstrips
SaveToolStripParameters();
base.Dispose(disposing);
}
private void LoadToolstripParameters()
{
if (DesignMode) return; // skips persistence if code being executed through VS Designer view
// Grab existing persisted settings and asign to temp store
StringCollection toolStripPanelItems = Properties.Settings.Default.ToolStripPanelItemLocations;
// Initiate delimited string
string delimitedString = String.Empty;
// Find any existing enrty for this ToolStripPanel
for (int i = toolStripPanelItems.Count - 1; i >= 0; i--)
{
if (toolStripPanelItems[i].StartsWith($"{this.Name}|"))
{
delimitedString = toolStripPanelItems[i];
break;
}
}
// Test if entry exists
if (delimitedString != String.Empty)
{
// remove the ToolStripPanel.Name text
string allTsParameters = delimitedString.Replace($"{this.Name}|", String.Empty);
// this pass removes the ToolStrip from the Panel and then re-adds them in reverse order at 0,0
// the strips are shifted right when a new one is added to the left
foreach (string individTsParameters in allTsParameters.Split(';'))
{
if (individTsParameters == "") continue;
// do the magic
string[] toolstripNameSplit = individTsParameters.Split(':');
Control toolstripControl = this.FindForm().Controls.Find(toolstripNameSplit[0], true).FirstOrDefault();
if (toolstripControl == null) continue; // controls for toolstrip names changed in designer (mismatch between persisted Name and new Name)
// first, de-parent
toolstripControl.Parent = null;
string[] toolStripSizeSplit = toolstripNameSplit[1].Split('-');
toolstripControl.Visible = true;
toolstripControl.Location = new Point(0, 0);
this.Controls.Add(toolstripControl);
}
// now strips are added, this changes the position of each toolstrip on the panel
foreach (string individTsParameters in allTsParameters.Split(';'))
{
if (individTsParameters == "") continue;
// do the magic
string[] toolstripNameSplit = individTsParameters.Split(':');
Control toolstripControl = this.FindForm().Controls.Find(toolstripNameSplit[0], true).FirstOrDefault();
if (toolstripControl == null) continue; // controls for toolstrip names changed in designer (mismatch between persisted Name and new Name)
string[] toolStripSizeSplit = toolstripNameSplit[1].Split('-');
if (!AutoArrange) // only repositions toolstrips if autoarrange set to false
{
toolstripControl.Location = new Point(Convert.ToInt16(toolStripSizeSplit[0].Split(',')[0])
, Convert.ToInt16(toolStripSizeSplit[0].Split(',')[1]));
}
toolstripControl.Visible = Convert.ToBoolean(toolStripSizeSplit[1]);
}
}
}
private void SaveToolStripParameters()
{
if (DesignMode) return; // skips persistence if code being executed through VS Designer view
// Grab existing persisted settings and asign to tmep store
StringCollection toolStripPanelItems = Properties.Settings.Default.ToolStripPanelItemLocations;
// Initiate the stringbuilder used in the persistence process
StringBuilder sb = new StringBuilder();
// Add the ToolStripPanel.Name to the stringbuilder
sb.Append($"{this.Name}|");
// Search existing settings for this ToolStripPanel and remove line if present (add it back later)
for (int i = toolStripPanelItems.Count - 1; i >= 0; i--)
{
if (toolStripPanelItems[i].StartsWith(sb.ToString())) toolStripPanelItems.RemoveAt(i);
}
List<Control> controls = new List<Control>();
foreach (Control control in this.Controls) controls.Add(control);
controls = controls.OrderByDescending(x => x.Location.X).ToList();
// All controls need to be visible before saving locaiotn. Therefore do a pass getting visibilites
Dictionary<string, bool> controlVisibilities = new Dictionary<string, bool>();
foreach (Control control in controls)
{
controlVisibilities.Add(control.Name, control.Visible);
control.Visible = true;
}
// Now add the delimited paramters for each ToolStrip in this ToolStripPanel
foreach (Control control in controls)
sb.Append($"{control.Name}:{control.Location.X},{control.Location.Y}-{controlVisibilities[control.Name]};");
// Add the new details to the temp store and then update the Setting.
toolStripPanelItems.Add(sb.ToString());
Properties.Settings.Default.ToolStripPanelItemLocations = toolStripPanelItems;
Properties.Settings.Default.Save();
}
}
它可能需要一些重构,但你已经死了很长时间了,对吧?