在ItemsControl中验证项目

6

我正在开发一款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类的列表:

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>

很不幸,即使它要求新人提供各种联系方式并符合有效输入的所有条件,下一步按钮仍然是看不见的。

出了什么问题?哪里出错了?

1个回答

6
你正在用不太好的方法尝试实现你想要的功能。这段代码中出现错误是因为你在样式触发器中引用了元素“txtContactValue”,但是样式根本不知道这个元素是什么。顺便说一下,如果你在调试代码时查看输出窗口,我打赌你会在那里看到这个错误。
现在,即使你尝试在没有样式的情况下引用“txtContactValue”,就像这样:
NextButtonVisibility="{Binding ElementName=txtContactValue, Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilitConverter}}"

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


那是个好主意,但不适用于我的情况。我正在尝试创建一个BingingGroup并将其设置为文本框元素和复选框元素...只有在复选框被选中且文本框通过模型中的验证有效时,NextButtonVisibility可见性才应该可见。例如:我在ItemControlSource中有两个项目,“group”正确填写,第二个复选框未选中且文本框为空,但所有内容都有效。 - Davecz
至少现在你知道代码中的错误在哪里了 :) - Evk
抱歉,可能有误解,但问题是关于描述行为时出现的错误:期望的行为是,如果复选框被选中,则显示带有输入联系人字段的网格,否则不显示。只有在选择的联系人类型有效时,下一步按钮才应该可见。此功能试图在app.xaml中实现以下样式。但是创建新属性来建模是个好主意 :-) - Davecz
1
我明白,但是你的样式无效 - 它引用了与该样式没有任何关系的“txtContactValue”元素,就像我在我的答案中所描述的那样。这就是我所说的“你现在知道错误出在哪里”的意思。 - Evk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接