【发布时间】:2020-11-10 17:40:26
【问题描述】:
在下面的 XAML 中,我使用 MultiDataTrigger 和 ValidationRule 尝试保留提交按钮 disabled,直到两个文本框输入了有效值(字母数字)。这可以正常工作,因为当值无效时(例如,some@test)按钮会被禁用,而当您使该值有效时(例如,sometest),它会启用按钮。
问题:但是当您启动应用程序时,它会将按钮显示为已启用 - 这违背了整个目的,因为即使您尚未开始输入文本框值也可以提交按钮。
问题:我可能在这里遗漏了什么,我们该如何解决?
备注:如果您查看(并且我测试了)上面第一个链接中的 MultiDataTrigger 示例,您会注意到(如两个图像所示)初始值(如预期的那样)显示为Unverified,颜色为red,当您选中两个复选框时,文本值将变为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 的 MultiDataTrigger.Conditions 块中的值 Validation.HasError 假定没有验证错误(因为应用程序刚刚加载并且用户尚未采取任何操作),因此它再次启用提交按钮。这只是我基于以下 XAML 的观察,我通过修改 MultiDataTrigger example 使用如下所示。在这里,我只是将TextBlock 更改为Button 以及相应的值,并注意到最初按钮被禁用(因为默认情况下复选框未选中),当您选中两个复选框时,按钮将启用(如预期的那样)。因此,我们可能需要了解如何(在上述 XAML 中)在应用初始加载时禁用该按钮。
网上修改的 XAML MiltiDataTrigger Example:
<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>
【问题讨论】:
标签: wpf validation xaml