【问题标题】:WPF NumericUpDown usercontrol in VB.netVB.net 中的 WPF NumericUpDown 用户控件
【发布时间】:2014-05-23 14:39:05
【问题描述】:

我正在 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;这意味着这个用户控件在某种程度上确实有效。我哪里做错了?为什么Textbox内容不会初始化为起始值?

经过更多测试。看来我的用户控件在“双向”中不起作用。它不从 DataTable 接收数据,它只将值传播给它。我该如何解决?

【问题讨论】:

  • 无关的,主要基于意见的评论:NumericUpDown 糟透了。这可能是 WPF 没有这个的主要原因。这些按钮太小且难以点击,并且在触摸设备中完全无法使用。通过为 MouseWheel 注册一个类事件处理程序并基于此增加/减少您的值,您会更好。只是一个建议。

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


【解决方案1】:

问题是您没有将txtNumText 属性绑定到您的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

请注意,仍然存在很多问题 - 用户可以输入超出允许范围的值,或者输入非数字数据(这会破坏事情!)等。对于这个特定问题,您可以查看 @ 987654321@,其中有各种up/down controls

【讨论】:

  • 关于这一点,WPF 似乎足够聪明,可以在最终用户向其中键入字符串时将用户控件标记为红色,这可能与 DataTable 中列的定义有关。我保留了 TextChanged 事件处理程序以防止用户输入超出范围的值。感谢您的友好回答。那里的大多数教程都使用 C# 而不是 VB。我可能也应该切换我的语言......
最近更新 更多