none
wpf 中只能输入正数,并且只有两位小数的textbox控件资料,请问什么地方有。 RRS feed

  • 问题

  • 各位好:

                 wpf 中只能输入正数,并且只有两位小数的textbox控件资料,请问什么地方有。

                  我试过百度。也试过wpftoolkit的控件。这个控件必须要离开焦点后才能变回两位小数。我希望是在控件中输入的时候就能控制。

    2017年8月22日 2:04

答案

  • 我找到答案了。来自于网上

    http://www.cnblogs.com/Joetao/articles/2848148.html

    不过他这个有两个小问题。

    一需要禁用输入法,否则用的时候会出问题。

    二,要限制长度,必须要在代码里面的构造函数中加上maxlength=7,这样子才能生效。

    • 已标记为答案 彭123 2017年8月24日 5:40
    2017年8月24日 5:40

全部回复

  • Hi,

    你可以使用正则表达式结合WPF的数据Validation来处理。

    public class sample2_ViewModel
        {
            private string _name;
    
            public string Name
            {
                get { return _name; }
                set
                {
                    _name = value;
                }
            }
        }
        public class InputValidationRule : ValidationRule
        {
            private string _errorMessage;
            public string ErrorMessage
            {
                get { return _errorMessage; }
                set { _errorMessage = value; }
            }
        
            public override ValidationResult Validate(object value, CultureInfo cultureInfo)
            {
                string input = value.ToString();
            
                bool rt = Regex.IsMatch(input,@"(^(0?)(\.\d{2}))|(^([1-9]\d*)(\.\d{2})$)");
                if (!rt)
                {
                    return new ValidationResult(false, this.ErrorMessage);
                }
                else
                {
                    return new ValidationResult(true, null);
                }
            }
        }
     <Window.DataContext>
            <local:sample2_ViewModel/>
        </Window.DataContext>
        <Grid>
            <TextBox x:Name="textBox" Height="23" Margin="35,45,32,0" TextWrapping="Wrap" VerticalAlignment="Top">
                <TextBox.Style>
                    <Style TargetType="{x:Type TextBox}">
                        <Setter Property="Validation.ErrorTemplate">
                            <Setter.Value>
                                <ControlTemplate>
                                    <DockPanel LastChildFill="True">
                                        <TextBlock  DockPanel.Dock="Bottom" Foreground="Red" FontSize="10pt" Text="{Binding ElementName=MyAdorner,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                        </TextBlock>
                                        <Border  BorderBrush="Red" BorderThickness="2">
                                            <AdornedElementPlaceholder Name="MyAdorner" />
                                        </Border>
                                    </DockPanel>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TextBox.Style>
                <TextBox.Text>
                    <Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:InputValidationRule  ErrorMessage="只能输入正数,并且只有两位小数" />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </Grid>



    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年8月22日 3:47
    版主
  • 楼上版主的方式是一种解决办法,但是请问还有那种不是显示错误,而是直接就无法往下输入的方式么。devexpress控件可以达到目的,但是他是收费的。
    2017年8月22日 5:05
  • 你好,

    >>楼上版主的方式是一种解决办法,但是请问还有那种不是显示错误,而是直接就无法往下输入的方式么。

    你的观点是一个悖论,TextBox不接受输入,如何进行输入匹配判断?

    你要知道当你输入第一个任意字符时,就已经不能匹配了,那你就不能使用无法输入的方式来处理了,因为一次只能输入一次字符,无论你输入什么你都得不到匹配。

    通常,限制输入的方式用于限制某一类字符的输入,比如你只希望输入数字,这时你可以处理PreviewTextInput事件,配合正则表达来进行匹配。

     private void textBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
            {       
                e.Handled = !Regex.IsMatch(e.Text, @"^[0-9]$");
            }

    如果我有任何误解,请详细描述你的需求。

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.





    2017年8月22日 5:37
    版主
  • 版主:

           我现在能够控制只有两位小数,但是有个问题就是最后光标定位时无法定位在最后一位。

    <Window x:Class="TextBox四舍五入.自定义四舍五入TextBox控件"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d"
            Title="自定义四舍五入TextBox控件" Height="300" Width="300">
        <Grid>
            <TextBox Width="200" Height="30" TextChanged="TextBox_TextChanged"/>
        </Grid>
    </Window>
    using System.Windows;
    using System.Windows.Controls;
    
    namespace TextBox四舍五入
    {
        /// <summary>
        /// 自定义四舍五入TextBox控件.xaml 的交互逻辑
        /// </summary>
        public partial class 自定义四舍五入TextBox控件 : Window
        {
            public 自定义四舍五入TextBox控件()
            {
                InitializeComponent();
            }
    
            private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                var v = e.Changes;
                TextBox tb = sender as TextBox;
                
                if (tb != null)
                {
                    if (string.IsNullOrWhiteSpace(tb.Text))//为空时不做处理
                    {
    
                    }
                    else
                    {
                        decimal c;
                        if (decimal.TryParse(tb.Text, out c))
                        {
                            int index = tb.Text.LastIndexOf(".");
                            if (index>0)//有小数,判断小数位数,
                            {
                                if (index+3<tb.Text.Length)
                                {
                                    tb.Text = tb.Text.Substring(0, tb.Text.Length - 1);
                                 
                                    tb.SelectionStart=tb.Text.Length;
                                    e.Handled = true;
                                }
                                else
                                {
                                    
                                    tb.SelectionStart = tb.Text.Length;
                                    e.Handled = true;
                                }
                            }
                            else//没有小数,不处理
                            {
    
                            }
                        }
                    }
                }
            }
        }
    }

    他最终一定会回到第一位。这是什么原因啊。


    • 已编辑 彭123 2017年8月23日 2:07
    2017年8月23日 2:06
  • Hi,

    不建议在TextChanged事件中处理,TextChanged事件会被执行多次,因为TextBox的Text的属性值改变都会触发这个事件。你可以尝试在PreviewTextInput事件中处理。

    private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
            {
                TextBox tb = sender as TextBox;
    
                if (tb != null)
                {
                    if (string.IsNullOrWhiteSpace(tb.Text))//为空时不做处理
                    {
    
                    }
                    else
                    {
                        decimal c;
                        if (decimal.TryParse(tb.Text, out c))
                        {
                            int index = tb.Text.LastIndexOf(".");
                            if (index > 0)//有小数,判断小数位数,
                            {
                                if (index + 3 < tb.Text.Length)
                                {
                                    tb.Text = tb.Text.Substring(0, tb.Text.Length - 1);
    
                                    tb.SelectionStart = tb.Text.Length;
                                    e.Handled = true;
                                }
                                else
                                {
    
                                    tb.SelectionStart = tb.Text.Length;
                                    e.Handled = true;
                                }
                            }
                            else//没有小数,不处理
                            {
    
                            }
                        }
                    }
                }
            }
        }

    但是我认为你这样做很大程度上增加了代码的复杂度,容易出错,起不到很好的验证作用,且用户体验不是很好。

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.



    2017年8月23日 6:08
    版主
  • 我找到答案了。来自于网上

    http://www.cnblogs.com/Joetao/articles/2848148.html

    不过他这个有两个小问题。

    一需要禁用输入法,否则用的时候会出问题。

    二,要限制长度,必须要在代码里面的构造函数中加上maxlength=7,这样子才能生效。

    • 已标记为答案 彭123 2017年8月24日 5:40
    2017年8月24日 5:40