设置控制值的通用方法

时间:2009-10-08 11:35:52

标签: c# asp.net generics

我正在尝试在aspx的代码中清理一些非常难看的形式填充代码,如下所示:

SchoolCensus1.Checked = (bool)questions[0].SchoolCensus1;
SchoolCensus1Info.Text = questions[0].SchoolCensus1Info;
SchoolCensus2.Checked = (bool)questions[0].SchoolCensus2;
SchoolCensus2Info.Text = questions[0].SchoolCensus2Info;
SchoolCensus3.Checked = (bool)questions[0].SchoolCensus3;
SchoolCensus3Info.Text = questions[0].SchoolCensus3Info;

这种情况持续了很长一段时间。

到目前为止我所拥有的是:

Type questionsType = questions[0].GetType();
PropertyInfo[] properties = questionsType.GetProperties();

        foreach (PropertyInfo property in properties)
        {
            if (property.PropertyType == typeof(Nullable<Boolean>))
            {
                CheckBox chkBox = container.FindControl(property.Name) as CheckBox;
                if (chkBox != null)
                    chkBox.Checked = (bool)property.GetValue(questions[0], null);
            }
            else if (property.PropertyType == typeof(String))
            {
                TextBox txtBox = container.FindControl(property.Name) as TextBox;
                if (txtBox != null)
                    txtBox.Text = (string)property.GetValue(questions[0], null);
            }
        }

这就是我需要它做的事情,但是我想把这一部分分解成一种方法来干掉它:

TextBox txtBox = container.FindControl(property.Name) as TextBox;
if (txtBox != null)
    txtBox.Text = (string)property.GetValue(questions[0], null);

有关应对不断变化的控制类型所需方法的建议吗?我猜测泛型是我需要的东西,但这确实不是我经验丰富的东西。

提前致谢!

2 个答案:

答案 0 :(得分:2)

小心你想要的......

无任何错误控制,但这里是第二个代码块的泛型版本。

static class ControlAssign
{

    public static void Assign(Control target, object source, PropertyInfo prop)
    {
        Setters[prop.PropertyType](prop, source, target);
    }

    static ControlAssign()
    {
        Setters[typeof(string)] = (prop, src, target) =>
        {
            ((TextBox)target).Text =
                (string)prop.GetValue(src, null);
        };

        Setters[typeof(bool?)] = (prop, src, target) =>
        {
            ((CheckBox)target).Checked =
                (bool)prop.GetValue(src, null);
        };

        Setters[typeof(bool)] = (prop, src, target) =>
        {
            ((CheckBox)target).Checked =
                (bool)prop.GetValue(src, null);
        };
    }

    public delegate void Action<T, U, V>(T t, U u, V v);

    readonly static Dictionary<Type, Action<PropertyInfo, object, Control>> Setters = new Dictionary<Type, Action<PropertyInfo, object, Control>>();
}

答案 1 :(得分:1)

我合作的其中一个项目通过

解决了这个问题
  1. 使用XML配置文件中的字段映射属性
  2. 定义一个通用方法,该方法将使用相应的属性填充每个字段。 这将涉及:
    • 从配置文件
    • 加载当前aspx页面中的所有数据
    • 对于列表中的每个控件,在页面上找到它并更新其值
  3. 不同类型的每个控件都需要不同的处理方式。我不确定如何使用泛型来使用常用方法来填充TextBox和CheckBox。

    另外,我注意到您正在根据属性类型决定使用的控件类型。即,说“string”类型的所有属性都映射到TextBox。但是将来您可能希望将字符串属性绑定到Label。

    而不是根据属性决定控件类型,你应该做这样的事情......

    foreach (PropertyInfo property in properties)
    {
        Control ctrl = container.FindControl(property.Name);
    
        if (ctrl != null)
        {
            if (ctrl is TextBox)
            {
                ((TextBox)ctrl).Text = (string)property.GetValue(questions[0], null);
            }
            else if (ctrl is Label)
            {
                ((Label)ctrl).Text = (string)property.GetValue(questions[0], null);
            }
            else if (ctrl is CheckBox)
            {
                (CheckBox)ctrl).Checked = (bool)property.GetValue(questions[0], null);
            }
    
            // etc.. for each control type
        }
    }