我正在尝试创建一个只允许正整数输入的TextBox,并且应该自动显示具有特定于文化的格式的输入(在本例中为en-US,因此它应该使用','符号作为分隔符对于更大的数字)。所以:
目前,在第一种情况下没有进行这样的自动格式化,第二种情况从我实现的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绑定到一个数值时,不允许空值。还有办法解决这个问题吗?
答案 0 :(得分:0)
答案 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("'", "");
}
}