簡體   English   中英

Foreach循環通過文本框的控件不返回

[英]Foreach loop through controls that are textbox doesn't return

我以前在另一個程序中使用過此代碼,但是現在我很難理解為什么第二行之后它無法運行該代碼。

foreach (Control c in Controls)
    if (c.GetType() == typeof(TextBox)) //doesn't run any further
    {
        if ((string)c.Tag == "Filled")
        {
            ...
        }
        ...
    }

我或者缺少一些小細節,或者其他不正確的東西。 有任何想法嗎?

編輯:我的文本框在面板內。

這樣做可能更簡單:

foreach ( TextBox tb in this.Controls.OfType<TextBox>()) 
{
    if ((string)tb.Tag == "Filled")
    // .....
}

要獲取所有控件(不僅是表單的直接子控件),可以使用此遞歸Linq

Func<Control, IEnumerable<Control>> allControls = null;
allControls = c => new Control[] { c }
                   .Concat(c.Controls.Cast<Control>()
                                     .SelectMany(x=>allControls(x)));

現在您可以過濾文本框

var tbs = allControls(this).OfType<TextBox>()
            .Where(t=>(string)t.Tag=="Filled")
            .ToList();

調用Control.Controls ,它將僅返回最外層的控件。 它不會遞歸地放入包含其他控件的任何容器控件中。

如果控件位於另一個容器中,則需要使用該容器的.Controls屬性。

或者,您可以編寫一種方法來歸納它,以遞歸地從父級及其所有子級返回所有控件,如下所示:

public IEnumerable<Control> AllControls(Control container)
{
    foreach (Control control in container.Controls)
    {
        yield return control;

        foreach (var innerControl in AllControls(control))
            yield return innerControl;
    }
}

然后可以使用它代替Control.Controls,如下所示:

private void test() // Assuming this is a member of a Form other class derived from Control
{
    var textboxesWithFilledTag = 
        AllControls(this).OfType<TextBox>()
        .Where(tb => (string) tb.Tag == "Filled");

    foreach (var textbox in textboxesWithFilledTag)
        Debug.WriteLine(textbox.Text);
}

就像評論所說,我假設test()方法是Form的成員,或者是Control派生的另一個類。 如果不是,則必須將父控件傳遞給它:

private void test(Control container)
{
    var textboxesWithFilledTag = 
        AllControls(container).OfType<TextBox>()
        .Where(tb => (string) tb.Tag == "Filled");

    foreach (var textbox in textboxesWithFilledTag)
        Debug.WriteLine(textbox.Text);
}

以下方法具有與上述方法相同的結果,以供參考(IMHO更具可讀性):

private void test(Control container)
{
    foreach (var textbox in AllControls(container).OfType<TextBox>())
        if ((string)textbox.Tag == "Filled")
            Debug.WriteLine(textbox.Text);
}

對於您的代碼,您的按鈕單擊處理程序可能看起來像這樣:

void button1_Click(object sender, EventArgs e)
{
    foreach (var c in AllControls(this).OfType<TextBox>())
    {
        if ((string) c.Tag == "Filled")
        {
            // Here is where you put your code to do something with Textbox 'c'
        }
    }
}

注意,當然,您還需要AllControls()方法。

最好使用if (c is TextBox) 此外,如果您想知道代碼為什么會中斷,請使用try / catch

我建議使用以下語法:

foreach (Control c in Controls)
    if (c is TextBox)

您是在自己設置標簽屬性嗎? 這是屬性的string類型。因此,您可以嘗試以下操作:

if (c.Tag == "Filled")
{
    Console.WriteLine(c.Name);
}

如果要檢查文本框是否為空,則可以嘗試以下操作:

if (c.Text.Trim().Length == 0)
{
 Console.WriteLine(c.Name);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM