验证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>

遗憾的是,下一步的按钮是不可见的,即使它要求新联系人的各种联系方式,并且将满足有效条目的所有条件。

怎么了?错误在哪里?

验证ItemsControl中的项

你试图以一种不太好的方式实现你想要的。这个特定代码中的错误是因为您从样式触发器引用了元素"txtContactValue",而样式根本不知道这个元素是什么。顺便说一下,如果您在调试代码时查看输出窗口,我打赌您会在那里看到这个错误。

现在,即使你试图引用没有样式的"txtContactValue",像这样:

NextButtonVisibility="{Binding ElementName=txtContactValue, Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilitConverter}}"

它不会工作,因为txtContactValue是在不同的作用域。但是你一开始就不应该这么做!你有一个数据模型,这个模型控制数据是否有效。只需添加一些属性到您的模型中,该属性指示您在此向导页面上创建的数据是否有效(如PersonContact.IsValid),然后您可以继续到下一页,并绑定到此属性。