【问题标题】:WPF TextBox to enter decimal valuesWPF TextBox 输入十进制值
【发布时间】:2013-06-04 09:26:55
【问题描述】:

是否有任何体面的方法来获得绑定到 decimal 值的 WPF 控件?

当我只是将TextBoxDataGridTextColumn 绑定到decimal 时,数据输入是个问题。

<TextBox Text="{Binding MyDecimal, UpdateSourceTrigger=PropertyChanged, 
    ValidatesOnDataErrors=True}"/>

当我尝试在这个TextBox 中输入“0,5”时,我会得到“5”。几乎不可能输入“0,5”(除了输入 1,5 并将“1”替换为“0”)。

当我使用StringFormat 时,数据输入只是略微改进:

<TextBox Text="{Binding MyDecimal, StringFormat=F1, UpdateSourceTrigger=PropertyChanged,
    ValidatesOnDataErrors=True}"/>

现在,当我尝试输入“0,5”时,我最终会得到“0,5,0”,这仍然是错误的,但至少我可以毫不费力地删除尾随的“,0”。

不过,使用 WPF 输入 decimal 类型还是很尴尬的,因为这些 TextBoxes 非常容易出现数据输入错误,尤其是对于值而言,这是一个真正的痛苦!

那么我应该在 WPF 中使用什么来输入十进制数据?还是微软不支持十进制数据??

【问题讨论】:

    标签: wpf decimal data-entry


    【解决方案1】:

    我目前将此行为用于数字和十进制输入:

    public class TextBoxInputBehavior : Behavior<TextBox>
    {
        const NumberStyles validNumberStyles = NumberStyles.AllowDecimalPoint |
                                                   NumberStyles.AllowThousands |
                                                   NumberStyles.AllowLeadingSign;
        public TextBoxInputBehavior()
        {
            this.InputMode = TextBoxInputMode.None;
            this.JustPositivDecimalInput = false;
        }
    
        public TextBoxInputMode InputMode { get; set; }
    
    
        public static readonly DependencyProperty JustPositivDecimalInputProperty =
         DependencyProperty.Register("JustPositivDecimalInput", typeof(bool),
         typeof(TextBoxInputBehavior), new FrameworkPropertyMetadata(false));
    
        public bool JustPositivDecimalInput
        {
            get { return (bool)GetValue(JustPositivDecimalInputProperty); }
            set { SetValue(JustPositivDecimalInputProperty, value); }
        }
    
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.PreviewTextInput += AssociatedObjectPreviewTextInput;
            AssociatedObject.PreviewKeyDown += AssociatedObjectPreviewKeyDown;
    
            DataObject.AddPastingHandler(AssociatedObject, Pasting);
    
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.PreviewTextInput -= AssociatedObjectPreviewTextInput;
            AssociatedObject.PreviewKeyDown -= AssociatedObjectPreviewKeyDown;
    
            DataObject.RemovePastingHandler(AssociatedObject, Pasting);
        }
    
        private void Pasting(object sender, DataObjectPastingEventArgs e)
        {
            if (e.DataObject.GetDataPresent(typeof(string)))
            {
                var pastedText = (string)e.DataObject.GetData(typeof(string));
    
                if (!this.IsValidInput(this.GetText(pastedText)))
                {
                    System.Media.SystemSounds.Beep.Play();
                    e.CancelCommand();
                }
            }
            else
            {
                System.Media.SystemSounds.Beep.Play();
                e.CancelCommand();
            }
         }
    
         private void AssociatedObjectPreviewKeyDown(object sender, KeyEventArgs e)
         {
            if (e.Key == Key.Space)
            {
                if (!this.IsValidInput(this.GetText(" ")))
                {
                    System.Media.SystemSounds.Beep.Play();
                    e.Handled = true;
                }
            }
         }
    
         private void AssociatedObjectPreviewTextInput(object sender, TextCompositionEventArgs e)
         {
            if (!this.IsValidInput(this.GetText(e.Text)))
            {
                System.Media.SystemSounds.Beep.Play();
                e.Handled = true;
            }
         }
    
         private string GetText(string input)
         {
            var txt = this.AssociatedObject;
    
            int selectionStart = txt.SelectionStart;
            if (txt.Text.Length < selectionStart) 
                selectionStart = txt.Text.Length;
    
            int selectionLength = txt.SelectionLength;
            if (txt.Text.Length < selectionStart + selectionLength) 
                selectionLength = txt.Text.Length - selectionStart;
    
            var realtext = txt.Text.Remove(selectionStart, selectionLength);
    
            int caretIndex = txt.CaretIndex;
            if (realtext.Length < caretIndex) 
                caretIndex = realtext.Length;
    
            var newtext = realtext.Insert(caretIndex, input);
    
            return newtext;
         }
    
         private bool IsValidInput(string input)
         {
            switch (InputMode)
            {
                case TextBoxInputMode.None:
                    return true;
                case TextBoxInputMode.DigitInput:
                    return CheckIsDigit(input);
    
                case TextBoxInputMode.DecimalInput:
                    decimal d;
                    //wen mehr als ein Komma
                    if (input.ToCharArray().Where(x => x == ',').Count() > 1)
                        return false;
    
    
                    if (input.Contains("-"))
                    {
                         if (this.JustPositivDecimalInput) 
                            return false;
    
    
                         if (input.IndexOf("-",StringComparison.Ordinal) > 0) 
                              return false;
    
                          if(input.ToCharArray().Count(x=>x=='-') > 1)
                              return false;
    
                            //minus einmal am anfang zulässig
                           if (input.Length == 1) 
                               return true;
                        }
    
                        var result = decimal.TryParse(input, validNumberStyles, CultureInfo.CurrentCulture, out d);
                        return result;
    
    
    
                default: throw new ArgumentException("Unknown TextBoxInputMode");
    
            }
            return true;
         }
    
         private bool CheckIsDigit(string wert)
         {
            return wert.ToCharArray().All(Char.IsDigit);
         }
    }
    
     public enum TextBoxInputMode
     {
      None,
      DecimalInput,
      DigitInput
      }
    

    XAML 用法如下所示:

    <TextBox Text="{Binding Sum}">
        <i:Interaction.Behaviors>
            <Behaviors:TextBoxInputBehavior InputMode="DecimalInput"/>
        </i:Interaction.Behaviors>
    </TextBox>
    

    【讨论】:

    • 看看这个,谢谢!你知道如何将它与 DataGridTextColumn 一起使用吗?
    • 当你先放一个减号时,我看到了一些奇怪的行为(它允许任何字符),否则是一个很好的解决方案!我将尝试在您的代码中找到错误,但我认为这可能需要一些时间,因为它有点扩展。感谢您的解决方案。
    • 我不使用字符串格式。而是使用转换器来代替这些东西。 ext="{Binding Path=MyValue, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=true, ValidatesOnDataErrors=true, NotifyOnValidationError=True, TargetNullValue={x:Static System:String.Empty}, Converter={StaticResource MyStringToDecimalConverter},ConverterParameter =#\,##0.00}"
    • 要获取Behavior&lt;TextBox&gt; 添加引用> 扩展> System.Windows.Interactivity
    • 作为 .net 5 或更高版本中的注释,这现在位于名为 Microsoft.Xaml.Behaviors.Wpf 的 nuget 包中。
    【解决方案2】:
        private void DecimalTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
        {
            bool approvedDecimalPoint = false;
    
            if (e.Text == ".")
            {
                if (!((TextBox)sender).Text.Contains("."))
                    approvedDecimalPoint = true;
            }
    
            if (!(char.IsDigit(e.Text, e.Text.Length - 1) || approvedDecimalPoint))
                e.Handled = true;
        }
    

    【讨论】:

    • 解释为什么此代码将解决 OP 的问题,而不是接受的答案...
    • 这也可以作为替代方案。由于十进制数必须容纳“。”字符,它被测试。只允许一个实例。更少的代码。
    • 这是一个比接受的答案更好的答案和更少的代码,这对于所请求的内容来说太过分了。通过添加 TextChanged 事件并添加以下代码可以轻松修复空间: if (myTextBox.Text.Contains(" ")) { myTextBox.Text = myTextBox.Text.Replace(" ", ""); myTextBox.CaretIndex = myTextBox.Text.Length; }
    • 全球化的思考,对于“非点”小数分隔符,德语中的逗号,例如..
    • @CMarsden 以下是改进此代码的建议:如果输入是点并且TextBox.Text 为空,则不赞成使用小数点以避免输入点作为第一个输入字符。
    【解决方案3】:

    WPF Extended toolkit 有一个DecimalUpDown 控件,可以满足您的需求。它是免费使用的,最好是使用它而不是尝试自己动手。

    至于验证其上的输入,有多种应用验证的方法,here is one 在 MSDN 中有详细说明。我在我的博客上的两篇文章中detail another approach 用于自定义可绑定验证(您可以将验证应用于 DecimalUpDown 控件上的 Value 属性绑定)。

    【讨论】:

    • 新控件意味着将您支持的所有主题应用到它们,这是一项繁重的工作。当所需的操作很简单时,几乎总是首选简约的附加属性或混合行为。
    【解决方案4】:

    我也遇到过这个问题;使用UpdateSourceTrigger=PropertyChanged,绑定似乎会在您键入文本时尝试更新文本。为了解决这个问题,我们更改了输入字段,以便 UpdateSourceTrigger=LostFocus,例如:

    <TextBox Text="{Binding MyDecimal, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True, StringFormat=n1}" />
    

    您可以使用IDataErrorInfo 接口定义自己的验证错误。您只需将以下内容添加到您的支持模型中:

     public class MyModel : IDataErrorInfo
     {
        /* my properties */
    
        public string Error { get { return null; } }
        public string this[string name]
        {
           get
           {
              switch (name)
              {
                 case "MyDecimal":
                    return NumberHelper.IsValidValue(MyDecimal) ? message : null;
                 default: return null;
              }
           }
        }
        private string message = "Invalid value";
     }
    

    【讨论】:

    • LostFocus 是 Text 属性的默认 UpdateSourceTrigger 值。完全不设置也会有同样的效果。
    • @dotsamuelswan,是的,但这是试图回答一个问题,我希望它是显而易见的。
    • 问题是:UpdateSourceTrigger 的设置是有原因的,否则当用户使用键盘快捷键调用按钮时,绑定值可能不会更新。
    • @Sam,啊,在这种情况下,这可能无济于事。不过我会保留它,因为在您不需要 PropertyChanged 的​​情况下,这是一个简单的解决方案,IMO。
    【解决方案5】:

    我实现了自己的文本框。当文本中有数字时,它会更新源,否则不会。在失去焦点时,我阅读了源属性。您所要做的就是将 TextBox 替换为此类并绑定 double 类型的“Number”属性。

    public class DoubleTextBox: TextBox
    {
        public DoubleTextBox()
        {
            TextChanged += DoubleTextBox_TextChanged;
            LostFocus += DoubleTextBox_LostFocus;
        }
    
        void DoubleTextBox_LostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            Text = Number.ToString("N2");
        }
    
        void DoubleTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            double zahl;
            if (string.IsNullOrWhiteSpace(Text))
            {
                Number = 0;
            }
            else if (double.TryParse(Text, out zahl))
            {
                Number = Double.Parse(zahl.ToString("N2"));
            }
            else
            {
                ValidationError validationError =
                    new ValidationError(new ExceptionValidationRule(), GetBindingExpression(NumberProperty));
    
                validationError.ErrorContent = "Keine gültige Zahl";
    
                Validation.MarkInvalid(
                    GetBindingExpression(NumberProperty),
                    validationError);
    
            }
        }
    
        public double Number
        {
            get { return (double)this.GetValue(NumberProperty); }
            set { this.SetValue(NumberProperty, value); }
        }
    
        public static readonly DependencyProperty NumberProperty = DependencyProperty.Register(
            "Number", typeof(double), typeof(DoubleTextBox), 
            new FrameworkPropertyMetadata
                (
                    0d,
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
                )
        );
    }
    

    【讨论】:

    • 我在尝试输入“123.40”时遇到问题 - 它不接受“0”
    【解决方案6】:

    从 .NET 4.5 开始,有一个更简单的修复方法,为绑定添加“延迟”

     <TextBox  Text="{Binding MyDouble, UpdateSourceTrigger=PropertyChanged, Delay=1000}" />
    

    用户现在有 1 秒 (1000 毫秒) 的时间在绑定系统尝试替换句点(将“1.”更改为“1”)之前。 这应该让他们有时间在“。”之后输入其他字符。这样它就不会被删除。

    【讨论】:

      【解决方案7】:

      如果您希望文本框只允许小数,则为该文本框编写 previewinputtext 事件。 然后在那种情况下编写此代码

      decimal result;
      e.Handled=!decimal.TryParse((sender as TextBox).Text + e.Text, out result)
      

      【讨论】:

        【解决方案8】:

        我知道这篇文章已经过时了,但它首先出现在 Google 搜索中以解决这个问题。由于 system.windows.interactivity 包(此包的旧版本)出现错误,我继续搜索。

        MSDN 上的这篇帖子解决了我的问题,它是一个在主窗口初始化组件之前的单行解决方案,如下所示:

            Public Sub New()
        
            ' This call is required by the designer.
            FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = False
            InitializeComponent()
        
            ' Add any initialization after the InitializeComponent() call.
        
        End Sub
        

        希望这对其他谷歌搜索者有所帮助。

        【讨论】:

          【解决方案9】:

          我是新手,所以我无法评论他的回答,但我修复了 blindmeis 代码中的负数问题。

          只需修改

          if (input.Contains("-"))
          

          IsValidInput() 部分到...

                          if (input.Contains("-"))
                          {
                              if (this.JustPositivDecimalInput)
                                  return false;
          
                              //minus einmal am anfang zulässig
                              //minus once at the beginning
                              if (input.IndexOf("-", StringComparison.Ordinal) == 0 && input.ToCharArray().Count(x => x == '-') == 1)
                              {
                                  if(input.Length == 1)
                                  {
                                      //INPUT IS "-"
                                      return true;
                                  }
                                  else if (input.Length == 2)
                                  {
                                      //VALIDATE NEGATIVE DECIMALS...INPUT IS "-."
                                      if (input.IndexOf(".", StringComparison.Ordinal) == 1)
                                      {
                                          return true;
                                      }
                                  }
                                  else 
                                  {
                                      return decimal.TryParse(input, validNumberStyles, CultureInfo.CurrentCulture, out d);
                                  }
                              }
                          }
          

          【讨论】:

            【解决方案10】:

            这个正则表达式有效

            private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
              {
               Regex regex = new Regex("^[.][0-9]+$|^[0-9]*[.]{0,1}[0-9]*$");
               e.Handled = !regex.IsMatch((sender as TextBox).Text.Insert((sender as TextBox).SelectionStart,e.Text));
              }
            

            【讨论】:

            • 谢谢,这行得通,你能解释一下这行 Regex("^[.][0-9]+$|^[0-9]*[.]{0,1}[0 -9]*$");
            【解决方案11】:

            这将只允许在文本框中输入小数,而不能输入其他内容。

            视图模型如下所示:

                private string _decimalVal = "0";
                public string decimalVal
                {
                    get { return _decimalVal.ToString(); }
                    set
                    {
                        if (string.IsNullOrEmpty(value) || value == "-")
                            SetProperty(ref _decimalVal, value);
                        else if (Decimal.TryParse(value, out decimal newVal))
                        {
                            if (newVal == 0)
                                value = "0";
            
                            SetProperty(ref _decimalVal, value = (value.Contains(".")) ? Convert.ToDecimal(value).ToString("0.00") : value);
                        }
                    }
                }
            

            XAML 用法如下所示:

            <TextBox Text="{Binding decimalVal,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
            

            【讨论】:

              【解决方案12】:

              我发现仅使用 PreviewTextInput 事件只会在您输入一些数字后想要输入负数时引起问题 1->12->123->-123(光标后移)

              在 PreviewTextInput 事件中移动插入符号这不起作用(作为 TextBox 发送).Text + e.Text

              使用以下内容获取正则表达式链接作为基础Decimal number regular expression, where digit after decimal is optional

              确定@"^[+-]?\d*.?\d*$" 这对我来说效果最好。

                  string previousText = "";
                  int previousCaretIndex = 0;
                  private void txtB_PreviewTextInput(object sender, TextCompositionEventArgs e)
                  {   
                      previousText = ((System.Windows.Controls.TextBox)sender).Text;
                      previousCaretIndex = ((System.Windows.Controls.TextBox)sender).CaretIndex;
                  }
              
                  private void txtB_TextChanged(object sender, TextChangedEventArgs e)
                  {
                      if(!Regex.IsMatch(((System.Windows.Controls.TextBox)sender).Text, @"^[+-]?\d*\.?\d*$"))
                      {
                          ((System.Windows.Controls.TextBox)sender).Text = previousText;
                          ((System.Windows.Controls.TextBox)sender).CaretIndex = previousCaretIndex;
                          e.Handled = true;
                      }
                  }
              

              【讨论】:

                【解决方案13】:

                通过这种方法可以防止将非整数和非十进制值复制和粘贴到TextBox,我在其他任何答案中都没有看到:

                private void TextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
                {
                    var textBoxText = ((System.Windows.Controls.TextBox)sender).Text;
                    var regex = new System.Text.RegularExpressions.Regex(@"^\d+\.?\d*$");
                    if (textBoxText.Length > 0)
                    {
                        textBoxText += e.Text;
                        e.Handled = !regex.IsMatch(textBoxText);
                    }
                    else
                    {
                        e.Handled = !regex.IsMatch(e.Text);
                    }
                }
                
                private void TextBox_PreviewExecuted(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
                {
                    if (e.Command == System.Windows.Input.ApplicationCommands.Paste)
                    {
                        if (System.Windows.Clipboard.ContainsText())
                        {
                            e.Handled = !new System.Text.RegularExpressions.Regex(@"^\d+\.?\d*$").IsMatch(System.Windows.Clipboard.GetText());
                        }
                    }
                }
                
                // In case user copies and pastes 2 times or more.
                // E.G. "1.0" might give "1.01.0" and so on.
                // E.G. if the regex expression is for the range of 1-100.
                // Then user might delete some numbers from the input which would give "0" or "00" etc.
                private void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
                {
                    var textBox = (System.Windows.Controls.TextBox)sender;
                    if (!new System.Text.RegularExpressions.Regex(@"^\d+\.?\d*$").IsMatch(textBox.Text.Trim()))
                    {
                        textBox.Clear();
                    }
                }
                

                XAML:

                <TextBox PreviewTextInput="TextBox_PreviewTextInput" CommandManager.PreviewExecuted="TextBox_PreviewExecuted" TextChanged="TextBox_TextChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/>
                

                顺便说一句,如果您想更改其行为以接受其他模式(例如正则表达式),您可以将正则表达式:@"^\d+\.?\d*$" 更改为适合您需要的其他内容,这种方法似乎更简单,并且可靠。

                编辑

                在某些情况下取决于正则表达式,例如HH:mm:ss 的日期时间正则表达式,其中TextChanged 不接受类似 00: 的内容,因为您键入试图实现 00:20:00 时将停止在第三个数字 00: 处,所以在这种情况下,如果您不'没有更好的正则表达式,而不是使用TextChanged 使用以下:

                private void TextBox_LostFocus(object sender, System.Windows.RoutedEventArgs e)
                {
                    var textBox = (System.Windows.Controls.TextBox)sender;
                    var textBoxText = textBox.Text.Trim();
                    if (textBoxText.Length == 0)
                    {
                        this.error = false; // It can be true too, depends on your logic.
                    }
                    else
                    {
                        this.error = !new System.Text.RegularExpressions.Regex(@"^\d+\.?\d*$").IsMatch(textBoxText);
                
                        if (this.error)
                        {
                            textBox.Background = System.Windows.Media.Brushes.Red;
                        }
                        else
                        {
                            textBox.ClearValue(System.Windows.Controls.TextBox.BackgroundProperty);
                        }
                    }
                }
                

                error 变量是一个成员变量,您应该使用它在表单末尾进行验证,例如通过点击一个按钮。

                【讨论】:

                  【解决方案14】:

                  这是我部分基于其他答案的解决方案。 控件“DoubleTextBox”包含可用于设置小数位数的属性“DecimalCount”。还处理了复制/粘贴、MVVM 和选择问题。 它尚未经过全面测试,可能包含错误。如果是这样,我稍后会更新帖子。

                  XAML:

                  xmlns:local_validators="clr-namespace:YourApp.validators"
                  xmlns:local_converters="clr-namespace:YourApp.converters"
                  
                  ..
                  
                  <local_controls:DoubleTextBox x:Name="tbPresetDose" DecimalCount="{Binding PresetDoseDecimalPointsCount}">
                      <TextBox.Resources>
                          <local_converters:DecimalPlaceStringFormatConverter x:Key="decimalPlaceStringFormatConverter"/>
                      </TextBox.Resources>
                      <TextBox.Text>
                          <MultiBinding Converter="{StaticResource decimalPlaceStringFormatConverter}">
                              <Binding Path="PresetDose"/>
                              <Binding Path="PresetDoseDecimalPointsCount"/>
                          </MultiBinding>
                      </TextBox.Text>
                  </local_controls:DoubleTextBox>
                  

                  DoubleTextBox 控件:

                  public class DoubleTextBox : TextBox
                  {
                      public DoubleTextBox()
                      {
                          DataObject.AddPastingHandler(this, OnPaste);
                          PreviewTextInput += DoubleTextBoxPreviewTextInput;
                      }
                      private void OnPaste(object sender, DataObjectPastingEventArgs e)
                      {
                          if (e.DataObject.GetDataPresent(typeof(string)))
                          {
                              var pastedText = (string)e.DataObject.GetData(typeof(string));
                  
                              if (!IsValidInput(pastedText))
                              {
                                  System.Media.SystemSounds.Beep.Play();
                                  e.CancelCommand();
                              }
                          }
                          else
                          {
                              System.Media.SystemSounds.Beep.Play();
                              e.CancelCommand();
                          }
                      }
                      private void DoubleTextBoxPreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
                      {
                          String text;
                  
                          if (!String.IsNullOrEmpty(this.SelectedText))
                          {
                              text = this.Text.Remove(this.SelectionStart, this.SelectionLength);
                              text = text.Insert(this.CaretIndex, e.Text);
                          } 
                          else
                          {
                              text = this.Text.Insert(this.CaretIndex, e.Text);
                          }
                  
                          e.Handled = !IsValidInput(text);
                      }
                      public bool IsValidInput(string value)
                      {
                          if (String.IsNullOrEmpty(value))
                              return false;
                  
                          string decimalNumberPattern = @"^[0-9]+(,[0-9]{0," + DecimalCount + @"})?$";
                          var regex = new Regex(decimalNumberPattern);
                          bool bResult = regex.IsMatch(value);
                          return bResult;
                      }
                      public void DecimalCountChanged()
                      {
                          try
                          {
                              double doubleValue = double.Parse(Text, System.Globalization.CultureInfo.InvariantCulture);
                              Text = doubleValue.ToString("N" + DecimalCount);
                          }
                          catch
                          {
                              Text = "";
                          }
                      }
                      public double DecimalCount
                      {
                          get { return (double)this.GetValue(DecimalCountProperty); }
                          set
                          { 
                              this.SetValue(DecimalCountProperty, value);
                              DecimalCountChanged();
                          }
                      }
                      public static readonly DependencyProperty DecimalCountProperty = DependencyProperty.Register(
                          "DecimalCount", typeof(double), typeof(DoubleTextBox),
                          new FrameworkPropertyMetadata
                              (
                                  0d,
                                  FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
                              )
                      );
                  }
                  

                  DecimalPlaceStringFormatConverter:

                  public class DecimalPlaceStringFormatConverter : IMultiValueConverter
                  {
                      public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
                      {
                          if (!decimal.TryParse(values[0].ToString(), out decimal value))
                              return values[0].ToString();
                  
                          if (!int.TryParse(values[1].ToString(), out int decimalPlaces))
                              return value;
                  
                          if (values.Length == 2)
                              return string.Format($"{{0:F{decimalPlaces}}}", value);
                          else
                              return value;
                      }
                  
                      public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
                      {
                          object dResult = DependencyProperty.UnsetValue;
                          string strValue = value as string;
                          double parcedDouble;
                          if (double.TryParse(strValue, out parcedDouble))
                          {
                              dResult = parcedDouble;
                          }
                  
                          return new object[] { dResult };
                      }
                  }
                  

                  视图模型:

                  private short _presetDoseDecimalPointsCount = 2;
                  
                  ..
                  
                  public short PresetDoseDecimalPointsCount
                  {
                      get => this._presetDoseDecimalPointsCount;
                      set
                      {
                          if (value != _presetDoseDecimalPointsCount)
                          {
                              _presetDoseDecimalPointsCount = value;
                              OnPropertyChanged();
                          }
                      }
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-03-28
                    • 2011-06-18
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-09-21
                    相关资源
                    最近更新 更多