1

有没有办法使用基类访问控件的值/文本?

查看TextBoxHiddenField, System.Web.UI.Control 是它们共享的最具体的基类。似乎是一个不错的候选人,但我看不到访问文本/值的明显方法。

我确实看到两个类定义都使用ControlValuePropertyAttribute来识别保存其文本/值的属性...例如 HiddenField 设置为“Value”,TextBox 设置为“Text”。不过,不确定如何使用该信息来检索数据。

背景

我有一个扩展方法,它获取一些 Web 控件(例如 TextBox)的文本并将其转换为给定类型:

<Extension()> _
Public Function GetTextValue(Of resultType)(ByVal textControl As ITextControl, ByVal defaultValue As resultType) As resultType
    Return ConvertValue(Of resultType)(textControl .Text, defaultValue)
End Function

现在,我需要一个 HiddenField 的值(它没有实现 ITextControl 接口)。重载函数很容易,但只处理基类而不必再处理编写重载就很棒了。

编辑 - 附加信息

这是如何使用扩展方法的示例

Dim myThing as Decimal = tbSomeWebControl.GetTextValue(Of Decimal)(0)  ' Converts the textbox data to a decimal
Dim yourThang as Date = hdnSomeSecret.GetTextValue(Of Date)(Date.MinValue)  ' Converts the hiddenfield data to a Date

目前,这需要两个重载,因为使用隐藏字段中的 Value 属性和文本框中的 Text 属性访问数据。

过载有什么问题?什么都没有,除了我一遍又一遍地编写几乎相同的代码(只是修改定义的第一个参数和它的调用的第一个参数)。

4

2 回答 2

4

您不能使用面向对象的方法来获取值,因为它们在继承树中没有共同的祖先,您可以从中获取数据。解决方案太不优雅了,你应该WebControl动态地传递和检查类型。

请原谅我的 C#:

(请注意,这是记事本代码,我没有运行任何代码,因此您可能需要一些调整)


方案一:直接从Request中获取数据

缺点:不是很像 ASP.NET。然而做这份工作。

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue)
{
    // If you only wish data from form, and not questy string or cookies
    // use Request.Form[control.UniqueId] instead
    string value = Request[control.UniqueId];
    return ConvertValue<ResultType>(value, defaultValue);
}

解决方案 2:动态检查类型

缺点:您必须为多种控件类型提供处理

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue)
{
    if (control is ITextControl)
        return ConvertValue<ResultType>((ITextControl)control.Text, defaultValue);
    else if (control is HiddenField)
        return ConvertValue<ResultType>((HiddenField)control.Value, defaultValue);
    else if (anothertype)
        return ConvertValue<ResultType>(another_retrieval_method, defaultValue);
}

解决方案 3:使用反射

缺点:反射可能很棘手,看起来不优雅,并且在许多调用上可能很慢

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue)
{
    // Get actual control type
    Type controlType = control.GetType();
    // Get the attribute which gives away value property
    Attribute attr = controlType.GetCustomAttribute<ControlValuePropertyAttribute>();
    if (attr == null)
        throw new InvalidOperationException("Control must be decorated with ControlValuePropertyAttribute");
    ControlValuePropertyAttribute valueAttr = (ControlValuePropertyAttribute)attr;
    // Get property name holding the value
    string propertyName = valueAttr.Name;
    // Get PropertyInfo describing the property
    PropertyInfo propertyInfo = controlType.GetProperty(propertyName);
    // Get actual value from the control object
    object val = propertyInfo.GetValue(control);
    if (val == null)
        val = "";

    return ConvertValue<ResultType>(val, defaultValue);
}
于 2013-02-19T15:37:46.400 回答
0

我认为DataItemContainer将是您正在寻找的最接近的东西。

于 2013-02-19T15:29:46.083 回答