如何保存动态创建的按钮

时间:2016-01-16 15:04:50

标签: c#

以下代码在Windows窗体c#中在运行时动态创建一个按钮。但在关闭/打开程序后,按钮会消失(不保存)。我认为按钮属性保存在Designer.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);

    }

3 个答案:

答案 0 :(得分:2)

非常肮脏和快速的方法,但它的工作原理:

    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

答案 1 :(得分:1)

如果动态创建控件,则无法将其保存到Designer.cs。只保存了您在Designer或HTML部分中创建的控件。

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

答案 2 :(得分:1)

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

一种方法是:

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

然后,在Form加载。如果在自定义文件中找到条目,则使用其信息重新创建Button。如果您没有找到Button的条目,那么您不会在表单上创建它。

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

如果您愿意,还可以使用数据库表替换自定义文件。