以下代码在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);
}
答案 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,您都会在自定义文件中创建一个条目,每当删除它时,都会删除它的条目。
如果您愿意,还可以使用数据库表替换自定义文件。