为什么使用TabPage.Controls使用for或foreach有什么不同?

时间:2015-07-23 12:16:17

标签: c# winforms for-loop foreach controls

我有问题,那就是:

TabPage tab = new TabPage();
[...]
for (int i = 0; i < tab.Controls.Count; i++)
{
   Debug.WriteLine(i + " - " + tab.Controls[i].Name + " - " + tab.Controls[i].Text);
}

显然与结果不一样:

TabPage tab = new TabPage();
[...]
int j = 0;
foreach (Control ctl in tab.Controls)
{
    Debug.WriteLine(j + " - " + ctl.Name + " - " + ctl.Text);
    j++;
}

for 循环在我的情况下是 53 项目(计数显示53),但 foreach 循环只有 27 项。

我无法理解这一点。可能是什么原因?

1 个答案:

答案 0 :(得分:0)

我现在可以自己解决问题:

第二个源代码不像发布它是这样的:

TabPage tab = new TabPage();
[...]
int j = 0;
foreach (Control ctl in tab.Controls)
{
    Debug.WriteLine(j + " - " + ctl.Name + " - " + ctl.Text);
    tab2.Controls.Add(ctl);
    j++;
}

=&GT;所以我在foreach循环中移动意外我的控件,但我只想克隆它,这就是答案:Clone Controls - C# (Winform)

现在我修理了它:

foreach (Control ctl in tab1.Controls)
{
    try
    {
        if (ctl != null)
        {
            object obj_clone = CloneObject(ctl);
            if (obj_clone != null && obj_clone is Control)
            {
                Control ctl_clone = (Control)CloneObject(ctl);
                tab2.Controls.Add(ctl_clone);
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception: " + ex.Message + " - TargetSite:" + ex.TargetSite + " - Source: " + ex.Source + " - InnerException: " + ex.InnerException.Message.ToString());
    }
}

private Object CloneObject(Object obj)
{
    var typ = obj.GetType();
    var obj_clone = CreateInstanceOfType(typ);
    PropertyInfo[] controlProperties = typ.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (PropertyInfo propInfo in controlProperties)
    {
        if (propInfo.CanWrite && propInfo.Name != "WindowTarget")
        {
            try
            {
                if (propInfo.PropertyType.IsValueType || propInfo.PropertyType.IsEnum || propInfo.PropertyType.Equals(typeof(System.String)))
                {
                    propInfo.SetValue(obj_clone, propInfo.GetValue(obj));
                }
                else
                {
                    object value = propInfo.GetValue(obj);
                    if (value == null)
                        propInfo.SetValue(obj_clone, null);
                    else
                        propInfo.SetValue(obj_clone, CloneObject(value));
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception: " + ex.Message + " - TargetSite:" + ex.TargetSite + " - Source: " + ex.Source + " - InnerException: " + ex.InnerException.Message.ToString());
            }
        }
    }
    return (Object)obj_clone;
}

public object CreateInstanceOfType(Type type)
{
    // First make an instance of the type.
    object instance = null;

    // If there is an empty constructor, call that.
    if (type.GetConstructor(Type.EmptyTypes) != null)
        instance = Activator.CreateInstance(type);
    else
    {
        // Otherwise get the first available constructor and fill in some default values.
        // (we are trying to set all properties anyway so it shouldn't be much of a problem).
        ConstructorInfo ci = type.GetConstructors()[0];
        ParameterInfo[] parameters = ci.GetParameters();

        object[] ciParams = new object[parameters.Length];

        for (int i = 0; i < parameters.Length; i++)
        {
            if (parameters[i].DefaultValue != null)
            {
                ciParams[i] = parameters[i].DefaultValue;
                continue;
            }

            Type paramType = parameters[i].ParameterType;
            ciParams[i] = CreateInstanceOfType(paramType);
        }

        instance = ci.Invoke(ciParams);
    }

    return instance;
}