如何保存动态创建的按钮

本文关键字:动态 创建 按钮 保存 何保存 | 更新日期: 2023-09-27 18:30:36

下面的代码在运行时在Windows窗体C#中动态创建一个按钮。 但是关闭/打开程序后,按钮消失(未保存)。我认为按钮属性保存在设计器中.cs(如果我是对的),但我不知道如何将其保存在那里。有人知道如何保存这个动态创建的按钮吗?谢谢

 private void button1_Click(object sender, EventArgs e)
    {
        // Create a Button object 
        Button dynamicButton = new Button();
        // Set Button properties
        dynamicButton.Height = 40;
        dynamicButton.Width = 300;
        dynamicButton.BackColor = Color.Red;
        dynamicButton.ForeColor = Color.Blue;
        dynamicButton.Location = new Point(20, 150);
        dynamicButton.Text = "I am Dynamic Button";
        dynamicButton.Name = "DynamicButton";
        dynamicButton.Font = new Font("Georgia", 16);

        dynamicButton.Click += new EventHandler(DynamicButton_Click);

        Controls.Add(dynamicButton);
    }

如何保存动态创建的按钮

非常肮脏和快速的方法,但它有效:

    string serializedButtonsPath = Path.GetDirectoryName(Application.ExecutablePath) + "''DynamicButtons.csv";
    private void button1_Click(object sender, EventArgs e)
    {
        // Create a Button object 
        Button dynamicButton = new Button();
        // Set Button properties
        dynamicButton.Height = 40;
        dynamicButton.Width = 300;
        dynamicButton.BackColor = Color.Red;
        dynamicButton.ForeColor = Color.Blue;
        dynamicButton.Location = new Point(20, 150);
        dynamicButton.Text = "I am Dynamic Button";
        dynamicButton.Name = "DynamicButton";
        dynamicButton.Font = new Font("Georgia", 16);
        //Naburi: Store function pointer before adding it to the event
        Action<object,EventArgs> dynamicButtonOnClick = dynamicButton_Click;
        dynamicButton.Click += new EventHandler(dynamicButtonOnClick);
        Controls.Add(dynamicButton);
        //Naburi: Serialize button (in strings)
        var membersData = new List<string>();
        membersData.Add(dynamicButton.Height.ToString());
        membersData.Add(dynamicButton.Width.ToString());
        membersData.Add(dynamicButton.BackColor.Name.ToString());
        membersData.Add(dynamicButton.ForeColor.Name.ToString());
        membersData.Add(dynamicButton.Location.X.ToString());
        membersData.Add(dynamicButton.Location.Y.ToString());
        membersData.Add(dynamicButton.Text);
        membersData.Add(dynamicButton.Name);
        membersData.Add(dynamicButton.Font.OriginalFontName);
        membersData.Add(dynamicButton.Font.Size.ToString());
        membersData.Add(dynamicButtonOnClick.Method.Name);
        //Naburi: Store data to csv TODO: improve format!!
        File.AppendAllText(serializedButtonsPath, string.Join(";", membersData) + Environment.NewLine);
    }
    private void button2_Click(object sender, EventArgs e)
    {//Naburi: load buttons
        var serializedButtons = File.ReadAllLines(serializedButtonsPath);
        foreach (var button in serializedButtons)
        {
            var membersData=button.Split(';');
            // Create a Button object 
            Button dynamicButton = new Button();
            // Set Button properties
            var i=0;
            dynamicButton.Height = int.Parse(membersData[i++]);
            dynamicButton.Width = int.Parse(membersData[i++]);
            dynamicButton.BackColor = Color.FromName(membersData[i++]);
            dynamicButton.ForeColor = Color.FromName(membersData[i++]);
            dynamicButton.Location = new Point(int.Parse(membersData[i++]), int.Parse(membersData[i++]));
            dynamicButton.Text = membersData[i++];
            dynamicButton.Name = membersData[i++];
            dynamicButton.Font = new Font(membersData[i++], float.Parse(membersData[i++]));
            //Store method name to make it independent of the index (i)
            var eventMethodName = membersData[i++];
            //Set the event by method name using reflection, the binding flags allow to access the private method
            dynamicButton.Click += (_sender, _e) => 
                    GetType().GetMethod(eventMethodName, BindingFlags.NonPublic|BindingFlags.Instance).Invoke(this, new[] { _sender, _e }
                );
            Controls.Add(dynamicButton);
        }
    }

使用 System.Reflection、System.Text 和 System.Collections.Generic

如果你有时间,你可以用更灵活的格式(如XML)进行更好的存储,也许可以创建一个.net序列化程序:https://msdn.microsoft.com/en-us/library/ms171834.aspx

如果动态创建按钮,则无法将其保存在设计器中。

一种方法是:

创建该按钮时,还会将重新创建按钮所需的信息存储在自定义文件(例如 XML)中。这些信息可能包括按钮的名称,其大小,位置,文本,前景色,背景颜色等,您需要重新创建按钮。

然后,在表单加载时。如果在自定义文件中找到条目,请使用其信息重新创建按钮。如果找不到按钮的条目,则不会在窗体上创建该条目。

但是,每当动态创建按钮时,都会在自定义文件中创建一个条目,无论何时删除它,都会删除其条目。

如果需要,还可以将自定义文件替换为数据库表。

如果动态创建控件,则无法将其保存到 Designer.cs。仅保存了在设计器或 HTML 部件中创建的那些控件。

如果需要保存动态创建的控件,可以将其参数存储到数据库或某个自定义文件中,从那里读取它们,在 C# 代码中动态创建新控件,并将这些参数应用于控件。