如何关闭 WPF 中的默认验证?

问题描述 投票:0回答:4

WPF 似乎有一些默认打开的验证规则。当我在绑定文本框中输入非数字文本并用 Tab 键将其移出时,它周围会显示一个读取边框。这里发生了什么?我已将 ValidatesOnExceptions 设置为 false,验证规则来自哪里?我正在使用 .Net 框架 4.5.2 版本。

这是我的 XAML

<Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication2"
            mc:Ignorable="d"
            Title="MainWindow" Height="159.206" Width="193.953">
        <Grid>
            <TextBox x:Name="textBox" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" TextWrapping="Wrap" 
                     Text="{Binding Foo, ValidatesOnExceptions=False, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
                     Width="91" Margin="10,10,0,0"/>
            <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="10,48,0,0" 
                     TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="91"/>
        </Grid>
</Window>

这是背后的代码

namespace WpfApplication2
{
    public partial class MainWindow : Window
    {
        public int Foo { get; set; } = 42;
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}
wpf
4个回答
2
投票

您可以从不

int
属性设置为除有效
int
值以外的任何值。

这种“验证”,或者更确切地说,编程语言的类型安全功能,无法关闭。

但是,如果您愿意,您可以删除或自定义默认错误模板。只需将

Validation.ErrorTemplate
属性设置为表情
ControlTemplate
:

<TextBox x:Name="textBox" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" TextWrapping="Wrap" 
        Text="{Binding Foo, ValidatesOnExceptions=False, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
        Width="91" Margin="10,10,0,0">
    <Validation.ErrorTemplate>
        <ControlTemplate />
    </Validation.ErrorTemplate>
</TextBox>

0
投票

在应用程序启动时,您可以将此调用添加到 FrameworkCompatibiltyPreferences 以禁止所有文本框干扰您的输入:

class App
{
    [STAThread]
    public static void Main(params string[] args)
    {     
        System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
        Application app = new Application();
        app.Run(new Window1());
    }
}

如果您使用数据绑定,文本框似乎仍会防止无效输入。将显示验证错误(默认为红色边框),并且视图模型属性不会设置为无效值。但现在您可以输入任何您想要的字符串。使输入绑定到 float 或 double 属性的十进制值变得更加容易。


0
投票

扩展 mm8 的出色答案,对于任何希望为可空

int
执行此操作的人,您可以执行以下操作;

XAML

<Window.Resources>
  <ResourceDictionary>
    <converters:NullableIntToStringConverter x:Key="NullableIntConverter" />
  </ResourceDictionary>
</Window.Resources>
<!-- ...snip ... -->
<TextBox Grid.Column="1" HorizontalAlignment="Stretch" Margin="5"              
         Text="{Binding Path=SearchRackNumber,Mode=TwoWay,Converter={StaticResource NullableIntConverter},ValidatesOnExceptions=False}"
         PreviewTextInput="TxtRackNumber_OnPreviewTextInput"
         PreviewKeyDown="TxtRackNumber_OnPreviewKeyDown">
  <Validation.ErrorTemplate>
    <ControlTemplate />
  </Validation.ErrorTemplate>
</TextBox>

代码背后

此处的事件阻止用户输入非数字字符。就我而言,我只关心正整数值。需要两个事件来处理大多数文本,以及单独的空格(请参阅here了解原因)。

private void TxtRackNumber_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
    var numericRegEx = new Regex("^[0-9]{0,10}$");
    e.Handled = !numericRegex.IsMatch(e.Text);
}

private void TxtRackNumber_OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    // a separate event is needed to handle the space as it doesn't trigger the
    // OnPreviewTextInput event. This is by WPF design to handle IME languages
    // (ones that take more than one key press to enter a character, e.g., Chinese).
    e.Handled = e.Key == Key.Space;
}

转换器

using System;
using System.Globalization;
using System.Windows.Data;

namespace YourApp
{
    internal class NullableIntToStringConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return null;
            return value.ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || string.IsNullOrWhiteSpace(value.ToString())) return null;

            var stringValue = value.ToString();
            if (!int.TryParse(stringValue, out int parsed)) return null;

            return parsed;
        }
    }
}

0
投票

我一直在寻找一个更简单的解决方案,代码最少,并且可以在样式中使用,这也有效:

XAML

<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>

© www.soinside.com 2019 - 2024. All rights reserved.