C# 具有自动区域性格式的文本框?

C# 具有自动区域性格式的文本框?,c#,.net,wpf,xaml,textbox,C#,.net,Wpf,Xaml,Textbox,我正在尝试创建一个只允许正整数输入的文本框,该文本框应自动显示具有区域性特定格式的输入(在本例中为en US,因此它应使用“,”符号作为较大数字的分隔符)。因此: 输入1000应在文本框中显示为“1000” 输入1000应显示为1000,但应正确解释 目前,在第一种情况下没有进行这样的自动格式化,第二种情况会触发ValidationRule中的错误,我已实现该规则来检查输入是否正确(它使用TryParse检查输入的有效数字) 我对全球化和国际化的思考还很陌生,所以我想知道是否有一些与som文

我正在尝试创建一个只允许正整数输入的文本框,该文本框应自动显示具有区域性特定格式的输入(在本例中为en US,因此它应使用“,”符号作为较大数字的分隔符)。因此:

  • 输入1000应在文本框中显示为“1000”
  • 输入1000应显示为1000,但应正确解释
目前,在第一种情况下没有进行这样的自动格式化,第二种情况会触发ValidationRule中的错误,我已实现该规则来检查输入是否正确(它使用TryParse检查输入的有效数字)

我对全球化和国际化的思考还很陌生,所以我想知道是否有一些与som文化相关的魔法可以帮助我将显示的格式从实际数据中分离出来,并在输入时使格式自动化

这是代码隐藏中文本框的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>
另一方面,我希望文本框能够显示为空-现在,文本框在加载时显示“0”,将文本框保留为空会触发验证错误(即使我在ValidationRule中允许)。据我所知,当我将文本框绑定为具有数值时,不允许使用空值。还有什么方法可以处理这个问题吗?

您可能会发现这很有用,请注意CultureInfo类


这篇文章有一个很好的解释。

好吧,我让它工作得很满意

  • 显然,我必须指定绑定专门应用于TextBox.Text元素(我不确定为什么从一开始就没有这样做)。在那之后,StringFormat就如广告一样工作了

  • 我为PreviewLostKeyboardFocus事件添加了一个相当简单的事件处理程序,它删除了组分隔符,因为我们要查找的值应该是一个未格式化的ulong-显示格式然后由我们的StringFormat转换器应用,因此预期的值不应该已经有任何此类格式(如果验证失败,则验证失败)。该事件还将删除任何潜在的前导零,以便更好地度量

我想上面的自动更正可能会以一种更漂亮的方式完成,使用一些regexp voodoo,但由于我不是那种特定品牌的houngan,这就是我想到的

谢谢大家的评论和想法

我的文本框背后的代码:

 <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>
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("'", "");            
    }
}

关于格式。您应该能够在绑定中使用完整的数字格式系统。例如{binding…,StringFormat='\{0:0;(0);\}'}'。即()中的负数和零值为零。现在,这正是我想要的。但是,当我在绑定中使用StringFormat时,我得到一个错误声明““StringFormat”转换器无法转换值“0”(类型“UInt64”);"等等…我唯一能想到的就是实现一个IValueConverter,但这对我来说似乎很奇怪-字符串和基本数字类型之间不应该有一个默认的转换吗?或者我还缺少其他东西吗?嗯。我肯定缺少一些东西。当我在上面的代码中使用绑定时,StringFormat转换器失败。但是当我删除绑定,而是包含一个“Text=…”行,并将绑定和StringFormat转换器添加到该行时,它就可以工作了。只要我显式地为转换器指定一个区域性…现在就来弄清楚如何使我的ValidationRules再次工作。
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);
        }
    }
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("'", "");            
    }
}