希望改进我的自定义Web控件文本框的百分比。 [英] Looking to improve my custom web control textbox for percentages.

查看:67
本文介绍了希望改进我的自定义Web控件文本框的百分比。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 the Text property or the Render method.

If you're binding to a database, it's also handy to have a second property typed as Object, which handles the conversion from DBNull.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆