在下面的XAML中,我使用MultiDataTrigger和ValidationRule试图保持提交按钮disabled,直到两个文本框中输入了有效值(字母数字)。它工作得很好,因为当值无效(例如,some@test)按钮被禁用,而当您使该值有效(例如,sometest)时,则启用该按钮。
问题:但是当您启动应用程序时,它会将按钮显示为已启用的按钮--这违背了所有的目的,因为您可以提交该按钮,即使您还没有开始输入文本框值。
问题:我在这里可能缺少了什么,我们如何解决它?
备注:如果您在上面的第一个链接中查看(我测试过) MultiDataTrigger示例,您会注意到(正如两个图像所示),初始值(如预期的那样)显示为带有red颜色的Unverified,而当您选中这两个复选框时,文本值将更改为带绿色的Verified。所以,很明显,我在上面的XAML中遗漏了一些东西。请注意,我已经将按钮的初始状态设置为<Setter Property="IsEnabled" Value="False"/>。
<Window x:Class="WPF_DataValidation.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:WPF_DataValidation"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        
        <local:MyDataSource x:Key="myds"/>
        <ControlTemplate x:Key="ValidationTemplate">
            <DockPanel>
                <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red" DockPanel.Dock="Bottom" Grid.Row="1"/>
                <AdornedElementPlaceholder/>
            </DockPanel>
        </ControlTemplate>
        <Style TargetType="Label">
            <Setter Property="Margin" Value="5" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>
        <Style x:Key="DefaultTextBoxStyle" TargetType="TextBox">
            <Setter Property="Margin" Value="5" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="Labels" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Label Name="lblFirstName">First Name:</Label>
        <TextBox Name="txtFirstName" Grid.Column="1" Style="{StaticResource DefaultTextBoxStyle}" Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
            <TextBox.Text>
                <Binding Path="FirstName" Source="{StaticResource myds}" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:AlphanumericOnlyValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Label Name="lblLastName" Grid.Row="1">Last Name:</Label>
        <TextBox Name="txtLastName" Grid.Row="1" Grid.Column="1" Style="{StaticResource DefaultTextBoxStyle}" Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
            <TextBox.Text>
                <Binding Path="LastName" Source="{StaticResource myds}" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:AlphanumericOnlyValidationRule />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Button x:Name="btnTest" Content="Test" Grid.Row="2" HorizontalAlignment="Right">
            <Button.Style>
                <Style TargetType="Button">
                    <Setter Property="IsEnabled" Value="False"/>
                    <Style.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtFirstName}" Value="False"/>
                                <Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtLastName}" Value="False"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="IsEnabled" Value="True"/>
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>MyDataSource.cs
public class MyDataSource
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}AlphanumericOnlyValidationRule.cs
using System.Windows.Controls;
using System.Linq;
using System.Globalization;
namespace WPF_DataValidation
{
    public class AlphanumericOnlyValidationRule: ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            string sVal = value as string;
            if (string.IsNullOrEmpty(sVal))
            {
                return new ValidationResult(false, "Please enter some text");
            }
            if (!sVal.All(char.IsLetterOrDigit))
            {
                //Note: this will also return false if text has a blank space
                return new ValidationResult(false, "This field must contain alphanumeric characcters only");
            }
            return new ValidationResult(true, null);
        }
    }
}观测
问题似乎是,当应用程序第一次加载时,它可能第一次禁用提交按钮。但是XAML的Validation.HasError块中的值MultiDataTrigger.Conditions假定没有验证错误(因为应用程序刚刚加载,用户还没有采取任何行动),因此它再次启用提交按钮。这只是我通过修改MultiDataTrigger实例使用的以下XAML的观察结果,如下所示。在这里,我将TextBlock与相应的值一起更改为Button,并注意到最初该按钮被禁用(因为默认情况下不选中复选框),并且当您选中这两个复选框时,按钮将被启用(如预期的那样)。因此,我们可能需要了解(在上面的XAML中),当应用程序最初加载时,我们如何禁用按钮。
从联机 MiltiDataTrigger实例中修改XAML
<Button.Style>
    <Style TargetType="Button">
         <Setter Property="IsEnabled" Value="False"/>
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtFirstName}" Value="False"/>
                        <Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtLastName}" Value="False"/>
                    </MultiDataTrigger.Conditions>
                  <Setter Property="IsEnabled" Value="True"/>
              </MultiDataTrigger>
            </Style.Triggers>
         </Style>
</Button.Style>发布于 2020-11-10 21:25:15
这是预期的行为,因为验证发生了。
(.)当目标的值被传输到绑定源属性时。
在您的示例中,在更新控件的值之前强制进行验证,您可以将ValidatesOnTargetUpdated="True"属性添加到ValidationRule中,并且在更新绑定的目标时它将触发验证。
<TextBox
    Name="txtLastName"
    Grid.Row="1"
    Grid.Column="1"
    Style="{StaticResource DefaultTextBoxStyle}"
    Validation.ErrorTemplate="{StaticResource ValidationTemplate}"
    >
    <TextBox.Text>
        <Binding
            Path="LastName"
            Source="{StaticResource myds}"
            UpdateSourceTrigger="PropertyChanged"
            >
            <Binding.ValidationRules>
                <local:AlphanumericOnlyValidationRule ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>https://stackoverflow.com/questions/64773959
复制相似问题