有没有一种方法可以动态生成代码以与C#中的按钮进行交互?

时间:2020-02-24 12:35:12

标签: c# winforms

我正在尝试找到一种方法,能够根据输入动态地生成代码。

例如,我可以输入类似的内容:

int Number = 22;
Button<Number>.Text = "X";

因此,在这种情况下,它将设置button22的文本为“ X”。

然后我可以对其进行更改,以便可以在程序中输入例如24,然后将button24设置为“ X”,而不是设置一堆if语句来覆盖每次可能的按钮按下。 / p>

对于其他情况,我有一个由64个按钮组成的网格,我需要能够对其进行单独编辑以向用户显示已按下了哪些按钮,可以使用很多if语句来完成此操作,但我认为也许值得尝试找到更优雅的解决方案。

3 个答案:

答案 0 :(得分:1)

您可能具有按钮列表:

private List<Button> _buttons = new List<Button>();

像这样填充它:

    for (int i = 0; i < 10; i++)
    {
        var b = new Button();
        b.Text = $"Button #{i}";
        b.Click += HandleButtonClick;
    }

您甚至可以在不需要使用列表的事件之一上设置事件处理程序(sender是事件的来源):

private void HandleButtonClick(object sender, EventArgs e)
{
    (sender as Button).Text = "X";
}

答案 1 :(得分:1)

按钮具有Tag属性,该属性可用于保存有关按钮的任意数据,有关WinFormsWPFUWP的描述。 this SO post

演示了类似于OP要求的简单用法

从实际的意义上讲,这种情况是.Tag在用户界面控件中完全存在的原因,从c#的诞生开始。

因此,您无需为按钮使用自定义类,只需将您的值分配给以编程方式创建的.Tag类的Button属性:

在此示例中,使用列表创建按钮并将创建与布局分开,这不是必需的,但可能很有用。相反,您可以将此按钮分配给它的父容器和/或设置布局边距或坐标,而根本不保留对Button对象的引用。
如果OP将帖子更新为包含实现示例,我们可以使用更具体,完整的代码来更新此响应。


private List<Button> _buttons = new List<Button>();
// ... iteration or switching logic 
var nextButton = new Button 
{ 
    Text = "x",
    Tag = 22
};
nextButton.Click += DynamicButton_Click;
_buttons.Add(nextButton);

// ... later push the buttons into the parent container or bind to the UI

然后单击按钮处理程序,您可以访问此Tag属性:

这是WinForms提供的,UWP或WPF的唯一区别是方法签名,将EventArgs更改为RoutedEventArgs


private void DynamicButton_Click(object sender, EventArgs e)
{
    if(int.TryParse((sender as Button).Tag?.ToString(), out int buttonValue))
    {
        // use buttonValue
        Console.Out.WriteLine(buttonValue);
    }
    else
    {
        // Otherwise, sender was not a button, or the button did not have an integer tag value
        // either way, handle that error state here...
    }
}

使用这些概念,一旦创建了按钮,就可以进行一些简单的网格对齐,如果您有一个TextBox(或其他)输入字段可以允许用户在运行时设置此Tag值,可从代码访问。

我建议您为此使用MVVM样式绑定,而不是直接引用TextBox控件,但这只是为了说明这一点。


private void DynamicButton_Click(object sender, EventArgs e)
{
    // assign the string value from the ButtonValueTextbox control to this button
    string value = this.ButtonValueTextBox.Text;
    if(sender is Button button)
    {
        button.Tag = value;
    }
    else
    {
        // Otherwise, sender was not a button
        // handle the error state here if you need to...
    }
}

现在每个按钮都有一个标记,您可以轻松地添加逻辑以通过迭代其他按钮并清除标记(如果先前已将其分配给其他按钮)来维护唯一的标记值。

答案 2 :(得分:0)

也许您可以保留List Button中的References

var myButtons = new List<Button>();
myButtons.Add(firstButton);
myButtons.Add(secondButton);

// ... etc

// ... then somewhere else 

int number = 3;
myButtons[number].Text = "xxx";