某些 Windows 窗体控件无法识别?

Posted

技术标签:

【中文标题】某些 Windows 窗体控件无法识别?【英文标题】:some windows form controls not recognized? 【发布时间】:2012-06-07 16:56:14 【问题描述】:

我有几个普通的 Windows 窗体。要清除其中一个中的数据输入字段,我使用如下代码:

    ClearInputFields(this);

    private void ClearInputFields(Control Page)
    
        try
        
            foreach (Control ctrl in Page.Controls)
            
                if (ctrl is Button)                    
                    continue;
                if (ctrl is DataGridView)
                    continue;
                if (ctrl is ListBox)
                    continue;

                if (ctrl is TextBox)
                
                    ((TextBox)(ctrl)).Text = string.Empty;
                
                else if (ctrl is ComboBox)
                        
                    ((ComboBox)(ctrl)).SelectedIndex = 0;
                
                else if (ctrl is CheckBox)
                
                    ((CheckBox)(ctrl)).Checked = false;
                
                else if (ctrl.Controls.Count > 0)
                
                    ClearInputFields(ctrl);
                                                       
            
        
        catch (Exception ex)
        
            TraceFile.Error("ExceptionLog", ex);
        
    

在其中一种形式上,它按预期工作。在另一种形式中,九个 ComboBox 中的两个没有被重置,六个 CheckBox 中的任何一个都不会被清除。

在调试器中单步执行,似乎特定控件甚至不在表单中包含的控件列表中。?!

我比较了表单,发现这些控件的属性没有什么不同。无法识别的组合框之一是数据绑定的,一个不是,但对于那些被重置的组合框也是如此。

我看过设计器,所有控件都声明为“this.Controls.Add(this.name_of_control);”

我已尝试省略最后一个“else if”(无论如何,此表单上没有面板、组框或其他容器)。行为上没有区别。

如果我明确地将复选框设置为“Checked = false”,并将 ComboBoxes 设置为“SelectedIndex = 0”,它们会按照我的预期执行,但在遍历表单控件时不会。

编辑 - 附录:所有控件都是在设计器中创建的,而不是在运行时创建的。如前所述,表单上没有容器。

我希望这是您眼皮底下的那些简单、明显的问题之一,但到目前为止我还没有看到它。

感谢任何见解。谢谢!

【问题讨论】:

您是否在运行时创建任何控件?比较 Page.Controls.Count 你的其他控件里面是否包含控件?您可能必须具有查找包含控件然后重新执行传递它的容器的逻辑。 @SASS_Shooter 代码已经在这样做了。它是递归的。 此代码将触发事件处理程序。如果您对事件处理程序中控件的 Z 顺序执行任何操作,那么您将遇到此问题。并注意例外情况。 啊哈!在某些情况下,我正在使用事件处理程序,但不是以任何有意或已知的方式改变任何事物的 Z 顺序。但是,这确实给了我改变方法的提示。 【参考方案1】:

也许在更改控件的属性时——this.Controls 中的控件顺序会发生变化,因此您不会遍历所有控件。虽然可能不是这种情况,因为Control ctrl in Page.Controls 可能只是第一次检查。

【讨论】:

在设置其中一个属性时更改控件的顺序肯定会解释这种行为,这就是我尝试单独循环的原因(尽管这可能不能保证顺序没有改变)。除了“愚蠢的运气”之外,这并不能解释为什么它适用于另一种形式。当然,这个逻辑的逻辑终点是您必须单独设置每个控件。【参考方案2】:

每当我必须对集合中的项目做一些可能会改变它的事情时,我通常会复制该集合,然后循环遍历该副本。在您的情况下,这是我通常编写的代码:

ClearInputFields(this);

private List<Control> ControlsForPage(Control Page)

        List<Control> result = new List<Control>();
        foreach (Control ctrl in Page.Controls)
              result.Add(ctrl);
        return result;


private void ClearInputFields(Control Page)

    try
    
        List<Control> ctrlsCopy = ControlsForPage(Page);
        foreach (Control ctrl in ctrlsCopy)
        
            if (ctrl is Button)                    
                continue;
            if (ctrl is DataGridView)
                continue;
            if (ctrl is ListBox)
                continue;

            if (ctrl is TextBox)
            
                ((TextBox)(ctrl)).Text = string.Empty;
            
            else if (ctrl is ComboBox)
                    
                ((ComboBox)(ctrl)).SelectedIndex = 0;
            
            else if (ctrl is CheckBox)
            
                ((CheckBox)(ctrl)).Checked = false;
            
            else if (ctrl.Controls.Count > 0)
            
                ClearInputFields(ctrl);
                                                   
        
    
    catch (Exception ex)
    
        TraceFile.Error("ExceptionLog", ex);
    

无论如何,为了了解这里发生了什么,我会尝试在重置之前制作 Controls 的副本,然后在重置后将其与页面的 Controls 集合进行比较。

【讨论】:

我希望我对每个项目所做的操作实际上不会改变集合,但这是一个很好的建议。我星期一回去工作时会试试这个。谢谢! 这没有任何效果,仔细想想,我不知道为什么会这样——除非我遗漏了一些东西。如果我正在制作每个控件的实际副本,我会清除我的副本,而不是表单上的控件。如果我复制对每个控件的引用,这应该表现得好像我只是在原始控件上进行操作(这就是它的作用)。 我没想到集合会改变,只是顺序

以上是关于某些 Windows 窗体控件无法识别?的主要内容,如果未能解决你的问题,请参考以下文章

CxFreeze 无法识别某些进口

Visual Studio 2015 无法识别 OTF 转换字体 (UWP)

IntelliJ 无法识别来自 gradle 项目的某些导入

为啥某些 Swift 标准库函数在 Playground 中无法识别?

windows 10 中用mklink 无法识别

在WinForms中无法识别用户控件