希望改进我的自定义Web控件文本框的百分比。 [英] Looking to improve my custom web control textbox for percentages.
问题描述
Code Project的精彩人物!
所以这是我的情况:
我有一个自定义文本框Web控件我已经设计了接受用户输入的百分比并将它们存储在十进制等值中(例如13.5=>0.135)。 Simillarly,当文本框被绑定时,它将从数据源获取十进制值并将其显示为其等效百分比(例如0.135=>13.5)。
Hello wonderful people of Code Project!
So here's my situation:
I have a custom textbox web control I've made that is designed to accept user input of a percentage and store them in its decimal equivalence (e.g. "13.5" => "0.135"). Simillarly, when the textbox is bound it will take the decimal value from the datasource and display it as its percentage equivalence (e.g. "0.135" => "13.5").
<DefaultProperty("Text"),
ToolboxData("<{0}:PercentageTextBox runat="server"></{0}:PercentageTextBox>")> _
Public Class PercentageTextBox
Inherits TextBox
Implements IValidator
#Region "Properties"
Public Property Editable As Boolean
Private ReadOnly Property InputFormatType As PercentageType
Get
Return PercentageType.InPercent ''Can be InDecimal if required
End Get
End Property
<Bindable(True),
Category("Appearance"),
DefaultValue(""),
Description("The name of the percentage"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty)>
Public Overridable Property Name As String
<Bindable(True),
Category("Appearance"),
DefaultValue(""),
Localizable(True)>
Overrides Property Text() As String
Get
Dim s As String = CStr(ViewState("Text"))
If s Is Nothing Then
Return String.Empty
Else
Return s
End If
End Get
Set(ByVal Value As String)
Dim output As String = Value
Try
''Convert percentage input to decimal.
Dim TextVal = CDec(Value)
Dim converted As New PercentageValue(TextVal, _
PercentageType.InDecimal)
output = CStr(converted.Value)
Catch ex As Exception
output = Value
Finally
ViewState("Text") = output
End Try
End Set
End Property
#End Region
Protected Overrides Sub Render(writer As HtmlTextWriter)
Try
If Editable Then
''Convert decimal value to percentage
Dim val = CDec(ViewState("Text"))
val = System.Math.Round(val * 10000, 2)
ViewState("Text") = val
End If
Catch ex As Exception
''Do something?
Finally
MyBase.Render(writer)
End Try
End Sub
End Class
NB我删除了添加到此控件的验证码;此外,您没有在控件本身中看到转换输入的数学,因为它使用类 PercentageValue
来转换基于枚举器的值 PercentageType
。这背后的想法是,这可以与将来基于 InputFormatType
属性的切换方法进行交互。
现在这是我制作的第一个自定义控件,所以我愿意尝试改进它的工作方式:
首先 :我不确定我的转换在控件中发生的位置。我应该在 Text()
方法中进行输入转换,在 Render()
方法中进行反转。我说这是因为当控件正在编辑存储值时,不必要地调用 Set
属性(导致我在 Render()中的转换
必须x10000才能撤消之前设定的通话。
其次:我正在创建该物业可编辑
需要在我使用控件时手动设置,例如在DetailsView中的EditItemTemplate中。这是为了将其与输入新值的用户区分开来。是否有继承文本框的某些属性可以推断出来而不必手动设置它?
任何指针或建议都会非常感激。
谢谢,
N.B. I stripped out the validation code added to this control; also, you don't see the math in the control itself for converting the input as it uses the class PercentageValue
to convert the value based upon the enumerator PercentageType
. The idea behind this was that this could be interacted with to switch method based on the InputFormatType
property in the future.
Now this is my first custom control I've made so I'm willing to try and improve how this works:
Firstly: I am not sure about where my conversion takes place in the control. Should I be doing the input conversion in the Text()
method and the inverse in the Render()
method. Reason I say this is that when the control is editing a stored value the Set
property is called unnecessarily (resulting in my conversion in Render()
having to x10000 to undo the previous set call).
Secondly: I've creating the property Editable
which needs to be set manually when I use the control, such as in an EditItemTemplate in a DetailsView. This is to distinguish it from a user inputting a new value. Is there some property of the inherited textbox that I can infer this from instead of having to set it as such manually?
Any pointers or advice would be much appreciated.
Thanks,
推荐答案
我过去使用的方法是添加一个新的可绑定属性对于负责解析和转换getter中的值的控件,并将值转换回setter中的字符串。这样,您无需触摸Text
属性或Render
方法。
如果您绑定到数据库,那么输入第二个属性Object
也很方便,它处理从DBNull
。
这样的东西:
The approach I've used in the past is to add a new bindable property to the control which takes care of parsing and converting the value in the getter, and converts the value back to a string in the setter. That way, you don't need to touch theText
property or theRender
method.
If you're binding to a database, it's also handy to have a second property typed asObject
, which handles the conversion fromDBNull
.
Something like this:
<DefaultProperty("Value"), ToolboxData("<{0}:PercentageTextBox runat="server">")> _
Public Class PercentageTextBox : Inherits TextBox
<Category("Data")>
Public Property Value() As Nullable(Of Decimal)
Get
Dim value As Decimal
If Not Decimal.TryParse(Me.Text, value) Then
Return Nothing
Else
Return value / 100
End If
End Get
Set(ByVal value As Nullable(Of Decimal))
If value Is Nothing Then
Me.Text = String.Empty
Else
value *= 100
Me.Text = value.ToString()
End If
End Set
End Property
<Bindable(True, BindingDirection.TwoWay), Category("Data")>
Public Property BoundValue() As Object
Get
Return Me.Value
End Get
Set(ByVal value As Object)
If value Is Nothing OrElse Convert.IsDBNull(value) Then
Me.Value = Nothing
Else
Me.Value = Convert.ToDecimal(value, CultureInfo.CurrentCulture)
End If
End Set
End Property
End Class
然后您可以使用 Value
来自代码的属性以正确的类型读取或设置值,并绑定到标记中的 BoundValue
属性:
You can then use the Value
property from code to read or set the value in the correct type, and bind to the BoundValue
property in markup:
<uc:PercentageTextBox id="SomePercentage" runat="server"
BoundValue='<%# Bind("SomePercentageFromTheDatabase") %>'
/>
这篇关于希望改进我的自定义Web控件文本框的百分比。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!