ToolStripManager 未恢复 Toolstrips 的位置

问题描述 投票:0回答:4

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);
        }
    }
}

Figure A Before closing form

Figure B Reopened form

Visual Studio 2010 - C# .Net 4 客户简介

c# winforms toolstrip
4个回答
1
投票

通过以下方式保存表单关闭设置:

ToolStripManager.SaveSettings(this);

通过以下方式加载表单加载中的设置:

ToolStripManager.LoadSettings(this);

0
投票

抱歉太快了...

您必须将其保存在配置文件或其他位置的某个位置,并在每次显示时检查这些值。

检查此代码片段

代码片段


0
投票

ToolStripContainer 的一个问题是您不能只设置包含 ToolStrip 的位置,因为容器总是检查容器中的其他 ToolStrip。

如果您在设计时没有将 ToolStrips 放入容器中,它可以正常工作。 您只需要一个函数来初始化它们一次。

另一种可能性是在调用 ToolStripManager.LoadSettings 函数之前将每个 Toolstrip 的父属性设置为 null


0
投票

以防万一其他人最终陷入 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();

    }

}

它可能需要一些重构,但你已经死了很长时间了,对吧?

© www.soinside.com 2019 - 2024. All rights reserved.