我可以在C#中使用某种“类”吗?

时间:2010-06-29 15:01:00

标签: c# casting

我想知道是否可以做某事。我有一个函数,它读取一个xml文件,并根据文件中的内容向表单添加控件。像这样的xml节点将创建它:

<Button Top="300" Left="100">Automatic</Button>

如果我在编辑模式下添加了任何控件,我有一个将控件保存回xml文件的函数。它工作正常,但我想知道是否有更简单的方法。目前,我有这样的代码来创建每个控件的实例:

            switch (xmlchild.Name)
            {
                // Create a new control whose type is specified.
                case "Button":
                    c = new Button();
                    break;
                case "Label":
                    c = new Label();
                    break;
                default:
                    c = null;
                    break;
            }

但是,当我想使用更多类型的控件时,我需要不断添加开关案例。我可以做一些只需要文本并添加该类型控件的东西吗?我将不胜感激任何反馈!

谢谢!

5 个答案:

答案 0 :(得分:2)

如果您控制XML文件的内容,那么是。你可以使用:

string fullNameSpace = "System.Windows.Controls.";
Type controlType = Type.GetType( fullNameSpace + xmlchild.Name );
if( controlType != null )
{
  // get default constructor...
  ConstructorInfo ctor = controlType.GetConstructor(Type.EmptyTypes);
  object control = ctor.Invoke(null);
}

你也可以使用Activator类来清理它:

object control = Activator.CreateInstance( "System.Windows.Presentation", 
                                           xmlchild.Name );

或者,如果您可以创建有效的XAML文件,则可以使用XamlReader来恢复控制树。

答案 1 :(得分:1)

您可以使用某些约定来保存自己的一些代码。基本上,使用反射来创建所需控件的实例,从XML传递代码。类似的东西:

Activator.CreateInstance(xmlchild.Name, ...)

只需填写正确的位,许多代码就会消失。

答案 2 :(得分:1)

听起来你正在寻找像Generics这样的东西。

您可以执行以下操作:

public static class ControlFactory
{
    public static T CreateControl<T>() where T : Type, new()
    {
        return new T();
    }
}

我还没有测试过这段代码,所以我会在测试时更新它。

答案 3 :(得分:1)

首先查看Activator类。然后,您可以将控件的类型名称存储为xml文件中的属性,并使用Activator类根据存储在当前xml元素的属性中的值创建实例(type =“fullTypeName”)。

此外,如果涉及属性,您可以考虑反射以基于属性名称在创建的实例上设置属性(即,您有一个控件实例 - 使用Activator类创建 - 并且您从Top属性分配值在xml中,可以使用反射获取/设置所创建实例的Top属性。

答案 4 :(得分:1)

可以像其他人描述的那样使用Reflection直接从其名称构造控件。但是,这种设计相当脆弱,如果XML文件是公开可见的,也可能引起安全问题,因为可以在运行时根据文件中的文本构造任意控件类型。这可能不是您特定应用的关注点。

我更喜欢使用Dictionary<string, Func<Control>>的设计,其中您有代码注册一个回调,为每个名称创建控件。这为您提供了一些额外的灵活性(您可以动态交换控制构造方法或组合来自多个源的可用控件)并且看起来也更干净(交换机被一些'寄存器'调用替换,实际构造分解为单独的方法或(在简单的情况下)作为lambda表达式)。如果使用MyImprovedTextBox替换应用程序中的TextBox并希望以前的配置文件使用改进版本,这也允许向后兼容。