所以我的程序生成了一堆按钮,如下所示:
foreach (var subdir in dir.GetDirectories()) {
var path = subdir.Name;
var button = new Button {
Text = getFlavor(path) + "\t(" + path + ")",
Width = Width,
Height = 35,
Top = y
};
button.Click += buttonClick;
Controls.Add(button);
if (button.Text.Contains("Kittens")
i++;
}
我想尝试这样的事情
if (i == 1) {
[Button.ThatContains("Kitten)].Click;
}
“ThatContains”不是一个真正的方法。如何获取我以编程方式创建的按钮的引用?
答案 0 :(得分:4)
您可以使用OfType<Button>
查找容器控件中已添加它们的所有按钮(例如,Panel
)。然后一个liitle位LINQ电源为您提供正确的按钮:
var kittenButtons = panel.Controls.OfType<Button>()
.Where(btn => btn.Text.Contains("Kittens"));
foreach(Button btn in kittenButtons)
btn.PerformClick();
如果您只想点击第一个:
Button kittenButton = panel.Controls.OfType<Button>()
.FirstOrDefault(btn => btn.Text.Contains("Kittens"));
if(kittenButton != null)
kittenButton.PerformClick();
对于它的价值,这里也是一个扩展方法,它通过延迟执行递归返回控件,允许仅使用第一个找到的Buttton
或消耗所有的东西:
public static IEnumerable<T> GetChildControlsRecursive<T>(this Control root) where T : Control
{
if (root == null) throw new ArgumentNullException("root");
var stack = new Stack<Control>();
stack.Push(root);
while (stack.Count > 0)
{
Control parent = stack.Pop();
foreach (Control child in parent.Controls)
{
if (child is T)
yield return (T)child;
stack.Push(child);
}
}
yield break;
}
现在您可以使用与上面类似的代码来获取第一个匹配按钮或全部:
var kittenButtons = this.GetChildControlsRecursive<Button>()
.Where(b => b.Text.Contains("Kittens"));
// search just until the first button is found
Button firstKittenButton = kittenButtons.FirstOrDefault();
if(firstKittenButton != null) firstKittenButton.PerformClick;
// loop all
foreach(Button btn in kittenButtons)
btn.PerformClick();
答案 1 :(得分:2)
创建Button的子类以存储您想要的信息并改为实例化或使用Tag
property
public class MyButton : Button
{
public int ButtonID { get; set; }
}
public class MyApplication
{
public void DoSomething()
{
int i; // todo: loop stuff
var button = new MyButton
{
Text = getFlavor(path) + "\t(" + path + ")",
Width = Width,
Height = 35,
Top = y,
ButtonID = i
};
}
}
或者为什么不将按钮点击事件的sender参数转换为Button并检查文本?
public class MyApplication
{
public void DoSomething()
{
var b = new Button();
b.Click += b_Click;
}
public void b_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
switch (b.Text) {
case "Kittens":
return;
default:
return;
}
}
}
答案 2 :(得分:1)
像这样的东西
var button = FirstOrDefault(y => y is Button && y.Text.Contains("Kittens"));
if(button != null)
button.PerformClick();
答案 3 :(得分:0)
为了获得引用,您可能需要使用任何其他类型的引用来做什么 - 将它们存储在某处,这在这里似乎并非如此。通常,您可以通过将按钮附加到Form
来注册用户进行交互的按钮。假设您没有通过示例代码的外观执行此操作,我建议将它们存储到Dictionary<string, Button>
中。
答案 4 :(得分:0)
您可以使用字典,也可以使用简单的递归循环(如果您将按钮固定在不同的容器中)。
private bool ClickButton(string buttonName, Control control) {
if (control is Button && control.Text.Contains(buttonName) {
((Button)control)PerformClick();
return true;
}
if (control.HasChildren) {
foreach (Control childControl in control.Controls) {
if (ClickButton(buttonName, childControl)) {
return true;
}
}
}
return false;
}
用法:ClickButton("Kittens", this);
或者您可以像某些人所建议的那样使用字典。
private Dictionary<string, Button> DynamicButtons = new Dictionary<string, Button>();
private void ClickDictionaryButton(string buttonName) {
var matches = DynamicButtons.Where(x => x.Key.Contains(buttonName));
foreach (var match in matches) {
match.Value.PerformClick();
}
}
用法:ClickDictionaryButton("Kittens", this);