验证ItemsControl中的项
本文关键字:ItemsControl 验证 | 更新日期: 2023-09-27 18:12:31
我正在开发一个WPF应用程序,在一个窗口中我使用了WPF工具包中的向导组件。在这个向导中,我正在创建一个新的人。在第二步中,我使用枚举作为可能的联系人类型的源(例如电话、电子邮件…)。
这是我在XAML中的向导页面:
<xctk:WizardPage x:Name="NewContactPage" PageType="Interior"
Title="Contacts" Style="{DynamicResource NewContactPage}"
CanCancel="True" CanFinish="False"
Loaded="NewContactPage_Loaded"
PreviousPage="{Binding ElementName=NewPersonPage}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Top">
<control:DataLoader x:Name="ctrNewContactLoader" />
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Top" Orientation="Vertical">
<ItemsControl ItemsSource="{Binding Path=Person.PersonContacts, Mode=TwoWay,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window}}"
Name="icContacts">
<ItemsControl.ItemTemplate>
<ItemContainerTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Top" Orientation="Vertical"
Margin="5" Background="WhiteSmoke">
<CheckBox IsChecked="{Binding Path=IsValid}"
Content="{Binding Path=ContactType.Description}"
Name="cbContactVisible"/>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Top"
Visibility="{Binding ElementName=cbContactVisible, Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Stretch" MaxLength="64"
Name="txtContactValue"
Text="{Binding Path=Contact,
ValidatesOnDataErrors=True,
ValidatesOnNotifyDataErrors=True,
ValidatesOnExceptions=True}" />
</Grid>
</StackPanel>
</ItemContainerTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
ItemsControl的源是一个PersonContactModel类的List:
public class PersonContactModel : BaseObjectModel
{
public PersonContactModel()
{
this.Created = DateTime.Now;
this.Updated = DateTime.Now;
this.IsValid = true;
this.ContactType = new ContactTypeModel();
}
public string Contact { get; set; }
public ContactTypeModel ContactType { get; set; }
public DateTime Created { get; set; }
public int Id { get; set; }
public bool IsValid { get; set; }
public DateTime Updated { get; set; }
public override string this[string columnName]
{
get
{
string retVal = string.Empty;
switch (columnName)
{
case "Contact":
retVal = base.Concat(base.RequeiredField(this.Contact), base.MinLength(this.Contact, 5), base.MaxLength(this.Contact, 62));
break;
}
return retVal;
}
}
}
基类实现了一个IDataErrorInfo接口,其中包含关于Contact属性的验证信息。
期望的行为是,如果复选框被选中,它是一个可见的网格,带有一个用于输入联系人的字段,否则不可见。只有当选择的联系人类型有效时,才能看到下一步按钮。这个功能试图在app.xaml中完成以下样式:
<Style TargetType="xctk:WizardPage" x:Key="NewContactPage">
<Setter Property="NextButtonVisibility" Value="Hidden" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtContactValue}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="NextButtonVisibility" Value="Visible" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
遗憾的是,下一步的按钮是不可见的,即使它要求新联系人的各种联系方式,并且将满足有效条目的所有条件。
怎么了?错误在哪里?
你试图以一种不太好的方式实现你想要的。这个特定代码中的错误是因为您从样式触发器引用了元素"txtContactValue",而样式根本不知道这个元素是什么。顺便说一下,如果您在调试代码时查看输出窗口,我打赌您会在那里看到这个错误。
现在,即使你试图引用没有样式的"txtContactValue",像这样:
NextButtonVisibility="{Binding ElementName=txtContactValue, Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilitConverter}}"
它不会工作,因为txtContactValue是在不同的作用域。但是你一开始就不应该这么做!你有一个数据模型,这个模型控制数据是否有效。只需添加一些属性到您的模型中,该属性指示您在此向导页面上创建的数据是否有效(如PersonContact.IsValid),然后您可以继续到下一页,并绑定到此属性。