WP.net中的WPF NumericUpDown用户控件

时间:2014-05-23 14:39:06

标签: wpf vb.net user-controls dependency-properties

我在VB中创建自己的NumericUpDown控件。这是我的XAML:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             x:Class="NumericUpDown"
             mc:Ignorable="d" 
             d:DesignHeight="30" d:DesignWidth="100">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="20" />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>
        <TextBox x:Name="txtNum" Grid.Column="0" x:FieldModifier="private" TextChanged="txtNum_TextChanged"/>
        <Button x:Name="cmdDown" Grid.Column="1" x:FieldModifier="private" Content="˅" Width="20" Click="cmdDown_Click" />
        <Button x:Name="cmdUp" Grid.Column="2" x:FieldModifier="private" Content="˄" Width="20" Click="cmdUp_Click" />
    </Grid>
</UserControl>

这是它背后的VB代码:

Class NumericUpDown

    Dim _Minimum As Double = 0
    Dim _Maximum As Double = 100

    Private Sub NumericUpDown()
        InitializeComponent()
        txtNum.Text = Numeric
    End Sub

    Public Property Maximum As Double
        Get
            Return _Maximum
        End Get
        Set(value As Double)
            _Maximum = value
        End Set
    End Property

    Public Property Minimum As Double
        Get
            Return _Minimum
        End Get
        Set(value As Double)
            _Minimum = value
        End Set
    End Property

    Public Shared ReadOnly NumericProperty As DependencyProperty = DependencyProperty.Register("Numeric", GetType(String), GetType(NumericUpDown), _
        New PropertyMetadata(""))

    Public Property Numeric As String
        Get
            Return CType(GetValue(NumericProperty), String)
        End Get
        Set(value As String)
            SetValue(NumericProperty, value)
        End Set
    End Property

    Private Sub cmdUp_Click(sender As Object, e As RoutedEventArgs)
        Dim NumValue As Double
        NumValue = Val(txtNum.Text)
        NumValue += 1
        If NumValue > Maximum Then NumValue = Maximum
        txtNum.Text = NumValue.ToString
    End Sub

    Private Sub cmdDown_Click(sender As Object, e As RoutedEventArgs)
        Dim NumValue As Double
        NumValue = Val(txtNum.Text)
        NumValue -= 1
        If NumValue < Minimum Then NumValue = Minimum
        txtNum.Text = NumValue.ToString
    End Sub

    Private Sub txtNum_TextChanged(sender As Object, e As TextChangedEventArgs)
        Numeric = txtNum.Text
    End Sub
End Class

我在我的页面中使用它像这样: 把它放在页面定义上:

xmlns:local="clr-namespace:Demo"

并将其放在内容部分:

<local:NumericUpDown Numeric="{Binding Path=score, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/>

当然我已经在容器上设置了DataContext,所有其他数据绑定控件都可以正常工作。但我的自定义控件中的文本框变空了!它并没有在这里结束。当我在文本框中输入内容时,当我使用减少和增加按钮给它一些值时,该值将传输到我的DataTable;这意味着这个用户控件在某种程度上可以工作。我哪里做错了?为什么不使用起始值初始化文本框内容?

经过多一点测试。似乎我的usercontrol不能在'双向'中工作。它不接收来自DataTable的数据,它只传播值给它。我该如何解决?

1 个答案:

答案 0 :(得分:2)

问题是您没有将Text txtNum属性绑定到您的Numeric媒体资源。

<TextBox x:Name="txtNum" Grid.Column="0" x:FieldModifier="private"
            Text="{Binding Path=Numeric, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>

然后您可以移除txtNum_TextChanged,并修改您的上/下点击处理程序,只需更新Numeric属性,例如:

Private Sub cmdUp_Click(sender As Object, e As RoutedEventArgs)
    If Me.Numeric < Me.Maximum Then
        Me.Numeric += 1
    Else
        Me.Numeric = Me.Maximum
    End If
End Sub

Private Sub cmdDown_Click(sender As Object, e As RoutedEventArgs)
    If Me.Numeric > Me.Minimum Then
        Me.Numeric -= 1
    Else
        Me.Numeric = Me.Minimum
    End If
End Sub

请注意,仍然存在许多问题 - 用户可以输入超出允许范围的值,或非数字数据(这将破坏事情!)等。对于此特定问题,您可以查看{ {3}},有各种Extended EPF Toolkit