具有自动文化格式的TextBox?

时间:2009-12-04 23:09:20

标签: c# .net wpf xaml textbox

我正在尝试创建一个只允许正整数输入的TextBox,并且应该自动显示具有特定于文化的格式的输入(在本例中为en-US,因此它应该使用','符号作为分隔符对于更大的数字)。所以:

  • 条目1000应在TextBox
  • 中显示为“1,000”
  • 1,000条目应该如此显示,但要正确解释......

目前,在第一种情况下没有进行这样的自动格式化,第二种情况从我实现的ValidationRule中触发错误,以检查输入是否正确(使用TryParse检查有效数字已经输入)。

我在全球化和国际化方面的思考方面很尴尬,所以我想知道是否存在与文化相关的魔术,我可以将显示的格式与实际数据分开并使格式自动化,在进入的时候?

这是代码隐藏的TextBox的xaml:

<TextBox 
                Foreground="{StaticResource WindowForegroundBrush}" 
                Background="{StaticResource EntryFieldBackgroundBrush}" 
                TextWrapping="NoWrap" 
                MaxLines="1" 
                MaxLength="100" 
                Margin="{StaticResource EntryFormTextBoxMargins}" 
                VerticalAlignment="Stretch" 
                RenderTransformOrigin="0.5,0.5" 
                HorizontalAlignment="Stretch" 
                VerticalContentAlignment="Center" 
                MinWidth="300" 
                MinHeight="30" 
                x:Name="PopTxtBox" 
                MaxWidth="300" 
                TextChanged="PopTxtChange">
                <Binding 
                    Path="locationPopulation"                                                 
                    Source="{StaticResource locDT}" 
                    UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <c:PopValidationRule />
                    </Binding.ValidationRules>
                </Binding>

这是我写的ValidationRule:

   public class PopulationValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            UInt64 popValue;

            if (value == null)
            {
                return new ValidationResult(true, null);
            }
            else if (!UInt64.TryParse((string)value, NumberStyles.AllowThousands, null, out popValue))
            {
                return new ValidationResult(false, "Value must be a valid number.");
            }

            return new ValidationResult(true, null);
        }
    }

顺便说一句,我希望TextBox能够显示为空 - 现在,TextBox在加载时显示“0”,而将TextBox保留为空会触发验证错误(即使我允许它在有效性规则)。据我所知,当我将TextBox绑定到一个数值时,不允许空值。还有办法解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

你可能会发现this很有用,关注CultureInfo类

This文章包含一个很好的解释..

答案 1 :(得分:0)

嗯,我让它让我满意。

  • 显然,我必须指定Binding专门应用于TextBox.Text元素(为什么我从一开始就没有这样做,我不确定)。之后,StringFormat按照宣传的方式工作。

  • 我为PreviewLostKeyboardFocus事件添加了一个相当简单的事件处理程序,它删除了组分隔符,因为我们要查找的值应该是无格式 ulong - 然后应用display-formatting我们的StringFormat转换器,因此预期的值不应该已经有任何这样的格式化(如果确实如此,则验证失败)。该事件还删除了任何潜在的前导零值以获得良好的衡量标准。

我想上面的自动修正可能会以更漂亮的方式完成,有一些正则表达式,但由于我不是那个特定品牌的成员,这就是我提出来的。

感谢大家的评论和想法!

我的TextBox的代码隐藏:

 <TextBox 
                Foreground="{StaticResource WindowForegroundBrush}" 
                Background="{StaticResource EntryFieldBackgroundBrush}" 
                TextWrapping="NoWrap" 
                MaxLines="1" 
                MaxLength="100" 
                Margin="{StaticResource EntryFormTextBoxMargins}" 
                VerticalAlignment="Stretch" 
                RenderTransformOrigin="0.5,0.5" 
                HorizontalAlignment="Stretch" 
                VerticalContentAlignment="Center" 
                MinWidth="300" 
                MinHeight="30" 
                x:Name="PopTxtBox" 
                MaxWidth="300" PreviewLostKeyboardFocus="PopTxtBoxLeavePreview"                                         
                >
                <TextBox.Text>
                    <Binding 
                        Path="locationPopulation"                                                 
                        Source="{StaticResource locDT}"                        
                        UpdateSourceTrigger="LostFocus"
                        StringFormat="{}{0:#,#;;}">
                        <Binding.ValidationRules>
                            <dataTemplates:PopValidationRule />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>

            </TextBox>

ValidationRule:

public class PopValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            ulong popVal;

            if (!ulong.TryParse((string)value, out popVal) && !(value == null))
            {
                return new ValidationResult(false, "ValidationResult: Not a number.");
            }

            return new ValidationResult(true, null);
        }
    }

PreviewLostKeyboard事件:

private void PopTxtBoxLeavePreview(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        TextBox senderBox = (TextBox)sender;

        //remove leading 0:s.
        senderBox.Text = senderBox.Text.TrimStart('0');
        //remove spaces as group separator
        senderBox.Text = senderBox.Text.Replace(" ", "");
        //remove commas as group separator
        senderBox.Text = senderBox.Text.Replace(",", "");
        //remove singlequotes as group separator
        senderBox.Text = senderBox.Text.Replace("'", "");            
    }
}