验证ListBox的内容不为空

托尼·维塔比(Tony Vitabile)

我的.NET 4.0 WPF应用程序有一个对话框,其中包含一个ListBoxListBox最初是空的。该对话框具有UI控件,允许用户将项目插入ListBox我正在使用MVVM和视图模型类实现IDataErrorInfo有一个ObservableCollection在其中结合到视图模型类ListBox's ItemsSource属性。

我不想让用户单击“确定”,直到他们在中至少输入了一项ListBox如果ListBox为空,我想在其周围显示一个红色边框,并在其右侧显示一个错误图标,并在ListBox's工具提示中显示错误消息这是所有其他错误在我的应用程序中显示的方式。

这是XAML的编辑版本:

<Window x:Class="MyDialog class's type"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:cs="clr-namespace:MyControlsDLL's namespace"
        xmlns:vm="clr-namespace:My View Model DLL's namespace"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        DataContext="{Binding Path=SelectedCamera, RelativeSource={RelativeSource Self}}"
        Loaded="MyDialog_Loaded"
        SizeToContent="Height"
        cs:ThemeSelector.CurrentThemeDictionary="{Binding Path=TimeOfDayTheme, RelativeSource={RelativeSource Self}}"
        Width="800"
        WindowStartupLocation="CenterOwner">

    <cs:MyDialog.CommandBindings>
        <cs:DataContextCommandBinding CanExecute="CanAddOrEditItem" Command="cs:MyCommands.AddItem"    Executed="AddOrEditItem" />
        <cs:DataContextCommandBinding CanExecute="CanRemoveItem"    Command="cs:MyCommands.RemoveItem" Executed="RemoveItem" />
    </cs:MyDialog.CommandBindings>

    <cs:MyDialog.Resources>
        <ResourceDictionary>
            <BitmapImage x:Key="ErrorImage" UriSource="Resources/Error.png" />

            <cs:BooleanInverter              x:Key="NOT" />
            <cs:BooleanToVisibilityConverter x:Key="BoolToVisibile"  True="Visible"   False="Collapsed" />
            <cs:BooleanToVisibilityConverter x:Key="BoolToCollapsed" True="Collapsed" False="Visible" />
            <cs:EnumToBooleanConverter       x:Key="SubTypeConverter" />
            <cs:MultiBoolConverter           x:Key="BoolCombiner" />

            <cs:EnumDisplayer ResourceManager="{x:Static res:MyApp.ResourceManager}" Type="{x:Type sys:DateTimeKind}" x:Key="DateTimeKinds">
                <cs:EnumOverride EnumValue="Local"       ResourceKey="DateKind_Local" />
                <cs:EnumOverride EnumValue="Unspecified" ResourceKey="DateKind_Unspecified" />
                <cs:EnumOverride EnumValue="Utc"         ResourceKey="DateKind_Utc" />
            </cs:EnumDisplayer>

            <cs:EnumDisplayer ResourceManager="{x:Static res:MyApp.ResourceManager}" Type="{x:Type vm:MyTypes}" x:Key="MyTypes" />

            <ControlTemplate x:Key="InputErrorTemplate">
                <DockPanel LastChildFill="True">
                    <Image DockPanel.Dock="Right"
                            Height="20"
                            Margin="-30,0,0,0"
                            Source="{StaticResource ErrorImage}"
                            ToolTip="{x:Static res:MyApp.Common_InvalidData}"
                            VerticalAlignment="Center"
                            Width="20" />
                    <Border BorderBrush="Red"
                            BorderThickness="5"
                            Margin="5,5,30,5">
                        <AdornedElementPlaceholder />
                    </Border>
                </DockPanel>
            </ControlTemplate>

            <Style TargetType="{x:Type ListBox}">
                <Setter Property="Validation.ErrorTemplate" Value="{StaticResource InputErrorTemplate}" />
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>

            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Validation.ErrorTemplate" Value="{StaticResource InputErrorTemplate}" />
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </cs:MyDialog.Resources>

    <Grid Name="LayoutRoot" Grid.IsSharedSizeScope="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <AdornerDecorator Grid.Row="0">
            <Grid Name="CommonRoot">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="5" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <TextBlock Grid.Column="0"
                           Grid.Row="0"
                           Margin="5"
                           Text="Name:"
                           TextAlignment="Right"
                           VerticalAlignment="Center" />
                <TextBox Grid.Column="1"
                         Grid.Row="0"
                         Margin="5,5,30,5"
                         MaxLength="50"
                         Name="NameBox"
                         TabIndex="0"
                         Text="{Binding Mode=TwoWay, NotifyOnSourceUpdated=True, Path=Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                         TextAlignment="Left"
                         VerticalAlignment="Center" />

                <TextBlock Grid.Column="3"
                           Grid.Row="0"
                           Margin="5"
                           Text="Type:"
                           TextAlignment="Right"
                           VerticalAlignment="Center" />
                <ComboBox Grid.Column="4"
                          Grid.Row="0"
                          Height="50"
                          ItemsSource="{Binding Source={StaticResource MyTypes}, Path=DisplayNames}"
                          SelectedValue="{Binding Converter={StaticResource MyTypes}, Mode=TwoWay, Path=MyType}"
                          SelectionChanged="LPRTypePicker_SelectionChanged"
                          Margin="5"
                          x:Name="MyTypePicker"
                          TabIndex="1"
                          VerticalAlignment="Center" />

                <TabControl Grid.Column="0"
                            Grid.ColumnSpan="6"
                            Grid.Row="1"
                            Name="Tabs">

                    <TabItem Header="Tab 1"
                             Name="Tab1">
                        <AdornerDecorator>
                            <Border BorderBrush="{DynamicResource ELDControlBorder}"
                                    BorderThickness="0,0,0,1">
                                <Grid Background="{DynamicResource ELDContentBackground}"
                                      Name="LPRConfiguration">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
                                        <ColumnDefinition Width="*" />
                                        <ColumnDefinition Width="5" />
                                        <ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
                                        <ColumnDefinition Width="*" />
                                        <ColumnDefinition Width="5" />
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <!-- Row definitions -->
                                    </Grid.RowDefinitions>

                                    <!-- Controls for this TabItem -->
                                </Grid>
                            </Border>
                        </AdornerDecorator>
                    </TabItem>

                    <TabItem Header="Directories List"
                             Visibility="{Binding Path=CanShow, Converter={StaticResource BoolToVisibile}}">
                        <AdornerDecorator>
                            <Border BorderThickness="0,0,0,1">
                                <Grid Name="Tab2Root">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="150" SharedSizeGroup="Column1" />
                                        <ColumnDefinition Width="3.5*" />
                                        <ColumnDefinition Width="110" />
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>

                                    <TextBlock Grid.Column="0"
                                               Grid.Row="0"
                                               HorizontalAlignment="Right"
                                               Margin="5"
                                               Text="Mode:" />

                                    <Grid Grid.Column="1"
                                          Grid.ColumnSpan="2"
                                          Grid.Row="0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="1*" />
                                            <ColumnDefinition Width="2*" />
                                            <ColumnDefinition Width="1*" />
                                            <ColumnDefinition Width="2*" />
                                            <ColumnDefinition Width="1*" />
                                        </Grid.ColumnDefinitions>

                                        <RadioButton Content="SubType 1"
                                                     Grid.Column="1"
                                                     GroupName="SubTypes"
                                                     IsChecked="{Binding Converter={StaticResource SubTypeConverter}, ConverterParameter=SubType1, Path=SubType}"
                                                     Margin="5"
                                                     TabIndex="8"
                                                     VerticalAlignment="Center" />
                                        <RadioButton Checked="SubType_Changed" 
                                                     Content="Value2"
                                                     Grid.Column="3"
                                                     GroupName="SubTypes"
                                                     IsChecked="{Binding Converter={StaticResource SubTypeConverter}, ConverterParameter=SubType2, Path=SubType}"
                                                     Margin="5"
                                                     Name="SubTypeSubType2Button"
                                                     TabIndex="8"
                                                     VerticalAlignment="Center" />
                                    </Grid>

                                    <TextBlock Grid.Column="0"
                                               Grid.Row="2"
                                               HorizontalAlignment="Right"
                                               Margin="5"
                                               Text="An Item:"
                                               VerticalAlignment="Center"
                                               Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />

                                    <Grid Grid.Column="1"
                                          Grid.Row="2"
                                          Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="Auto" />
                                        </Grid.ColumnDefinitions>

                                        <TextBox Grid.Column="0"
                                                 Margin="5"
                                                 Name="NewItemBox"
                                                 TabIndex="11"
                                                 Text="{Binding Mode=TwoWay, Path=NewItem, UpdateSourceTrigger=PropertyChanged}"
                                                 ToolTip="{x:Static res:MyApp.MyDialog_NewItem_Tooltip}"
                                                 VerticalAlignment="Center" />

                                        <Button Command="cs:MyCommands.Browse"
                                                Content="Browse..."
                                                Grid.Column="1"
                                                Height="35"
                                                Margin="5"
                                                Name="BrowseDirectoriesButton"
                                                TabIndex="12" />
                                    </Grid>

                                    <Button Command="cs:MyCommands.AddItem"
                                            Content="{Binding Path=AddOrEditLabel}"
                                            Grid.Column="2"
                                            Grid.Row="2"
                                            Height="50"
                                            Margin="5"
                                            Name="AddItemButton"
                                            TabIndex="13" />

                                    <TextBlock Grid.Column="0"
                                               Grid.Row="3"
                                               HorizontalAlignment="Right"
                                               Margin="5"
                                               Text="Selected Items:"
                                               TextAlignment="Right"
                                               TextWrapping="WrapWithOverflow"
                                               Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />

                                    <ListBox Grid.Column="1"
                                             Grid.Row="3"
                                             Height="160"
                                             ItemsSource="{Binding Path=SelectedItems}"
                                             Margin="5,5,30,5"
                                             Name="ItemsList"
                                             SelectedValue="{Binding Mode=TwoWay, Path=SelectedItem, ValidatesOnDataErrors=True}"
                                             TabIndex="14"
                                             Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />

                                    <Button Command="cs:MyCommands.RemoveItem"
                                            Content="Remove"
                                            Grid.Column="2"
                                            Grid.Row="3"
                                            Height="50"
                                            Margin="5"
                                            Name="RemoveItemButton"
                                            TabIndex="15"
                                            VerticalAlignment="Top"
                                            Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />
                                </Grid>
                            </Border>
                        </AdornerDecorator>
                    </TabItem>
                </TabControl>
            </Grid>
        </AdornerDecorator>

        <!-- OK & Cancel Buttons here -->
    </Grid>
</Window>

这里有一个复杂之处,即使ListBox它最初是空的,但是如果Type属性是一个值并且SubType属性是SubType1,则将其为空只是一个错误。最初,这些属性没有那些值。首次显示对话框时,我可以看到我的验证代码被调用,但是没有显示错误,因为ListBox甚至没有显示。

更改Type属性后,SubType属性将自动设置为SubType1并ListBox显示,并且该属性为空。我已经能够验证是否在视图模型类的IDataErrorInfo实现中调用了验证代码,并且返回了错误消息,但没有显示错误模板。实际上,该选项卡上根本没有显示任何错误,我认为它与显示错误的之前的选项卡相同。

我做错了ListBox什么?

编辑

有一个TextBoxon,Tab它最初也处于错误状态,并且未显示任何错误消息。当我在其中输入一些文本时,验证代码便已运行并且标记为“确定”。但是,当我清空它时,它的确显示了错误情况。也许我的问题是,当用户选择Type1或更改SubType时,我需要做一些事情以使其进入错误状态?

托尼·维塔比(Tony Vitabile)

我知道了。我在上添加ValidatesOnDataErrors=True了该ItemsSource属性的绑定ListBox,现在显示错误模板。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

验证ListBox的内容不为空

来自分类Dev

验证输入字段不为空

来自分类Dev

验证验证是否不为空

来自分类Dev

流利的验证收集项不为空/空

来自分类Dev

用jQuery验证div不为空

来自分类Dev

Laravel表单验证,如果不为空则失败

来自分类Dev

如何验证Mongoid中的数组不为空?

来自分类Dev

仅当字段不为空时验证

来自分类Dev

jQuery验证字段不为空时

来自分类Dev

用jQuery验证div不为空

来自分类Dev

如何验证地图的值不为空

来自分类Dev

PHP的尊重验证只是验证如果不为空

来自分类Dev

字段不为空时,验证失败为空

来自分类Dev

字段验证显示空指针异常,即使不为空

来自分类Dev

JavaScript表单验证不为空或没有空格

来自分类Dev

使用Selenium WebDriver验证文本字段不为空

来自分类Dev

验证规则,当字段不为空时发出警报

来自分类Dev

在Spring Data查询参数中验证集合不为空

来自分类Dev

Rails 5:如果字段不为空,则验证长度

来自分类Dev

JavaScript表单验证不为空或没有空格

来自分类Dev

在Spring Data查询参数中验证集合不为空

来自分类Dev

验证 Spring 控制器参数不为空

来自分类Dev

Cakephp 2 即使在字段不为空后也需要验证

来自分类Dev

Jquery 验证不为空并且是表单中的 URL

来自分类Dev

检查CSS标题属性(如果不为空)并添加内容

来自分类Dev

验证失败:电子邮件不能为空,密码不能为空-不为空

来自分类Dev

空参数不为空

来自分类Dev

语义UI表单验证-仅当值不为空时才验证某些表单字段

来自分类Dev

仅在不为空的情况下进行图像验证扩展验证