有没有办法使用基类访问控件的值/文本?
查看TextBox和HiddenField,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
目前,这需要两次重载,因为使用hiddenfields中的Value属性和文本框中的Text属性访问数据。
重载有什么问题?没什么,除了我一遍又一遍地编写几乎相同的代码(只修改定义的第一个参数和它的调用的第一个参数)。
答案 0 :(得分:4)
您无法使用面向对象的方法来获取值,因为它们在继承树中没有共同的祖先,您可以从中获取数据。解决方案非常优雅,您只需传递WebControl
并动态检查类型。
原谅我的C#:
(请注意,这是记事本代码,我没有运行任何代码,因此您可能需要进行一些调整)
解决方案1:直接从“请求”
获取数据下行:不是很好的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);
}
答案 1 :(得分:0)
我认为DataItemContainer将是您最接近的事情。