1

我需要有用户将定期附加/编辑的连接字符串列表。所以我定制了列表视图,它是数据绑定到一个可观察的集合。

<ListView x:Name="DGV_Env" Margin="5" FontSize="11" FontStyle="Italic" ItemsSource="{Binding Environments}" Background="White"
                                       HorizontalContentAlignment="Center" VerticalContentAlignment="Center" SelectedIndex="0" SelectionMode="Single"  >    
        <ListView.Resources>
        <Style TargetType="ListViewItem">           
            <Style.Triggers>                
                <Trigger Property="Validation.HasError" Value="True">
                    <Setter Property="BorderThickness" Value="3" />
                    <Setter Property="BorderBrush" Value="Red" />
                </Trigger>
                <Trigger Property="Validation.HasError" Value="False">
                    <Setter Property="BorderThickness" Value="0" />
                    <Setter Property="BorderBrush" Value="CadetBlue" />
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="IsSelected" Value="True" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="TextBox">
            <Setter Property="Validation.ValidationAdornerSite"  Value="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}}"/>          
        </Style>
        <Style TargetType="PasswordBox">
            <Setter Property="Validation.ValidationAdornerSite"  Value="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}}"/>
        </Style>
    </ListView.Resources>

    <ListView.View>
        <GridView x:Name="GV_Env_Column" AllowsColumnReorder="False">
            <GridView.ColumnHeaderContextMenu>
                <ContextMenu FontSize="12" Foreground="Black" />
            </GridView.ColumnHeaderContextMenu>
            <GridViewColumn Header="Slno"  >
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Slno}" HorizontalAlignment="Center" VerticalAlignment="Center"  FontSize="12" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>           
            <GridViewColumn Header="Server">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Margin="-2,0,-2,0"   BorderThickness="0"  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center"  FontSize="12"  Style="{StaticResource TextBoxStyle}" Tag="Server">
                            <TextBox.Text>
                                <Binding   Mode="TwoWay" Path="Server" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" >
                                    <Binding.ValidationRules>
                                        <local:NonEmptyStringValidator ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue" />
                                    </Binding.ValidationRules>
                                </Binding>
                            </TextBox.Text>
                        </TextBox>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Database">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Margin="-2,0,-2,0"    BorderThickness="0"  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center"  FontSize="12" Style="{StaticResource TextBoxStyle}" Tag="Database">
                            <TextBox.Text>
                                <Binding   Mode="TwoWay" Path="Database" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" >
                                    <Binding.ValidationRules>
                                        <local:NonEmptyStringValidator ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue" />
                                    </Binding.ValidationRules>
                                </Binding>
                            </TextBox.Text>
                        </TextBox>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="UserID">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Margin="-2,0,-2,0"   BorderThickness="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" FontSize="12" Style="{StaticResource TextBoxStyle}" Tag="User ID">
                            <TextBox.Text>
                                <Binding   Mode="TwoWay" Path="UserId" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" >
                                    <Binding.ValidationRules>
                                        <local:NonEmptyStringValidator ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue" />
                                    </Binding.ValidationRules>
                                </Binding>
                            </TextBox.Text>
                        </TextBox>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Password">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="White"  Margin="-2,0,-2,0" FocusManager.FocusedElement="{Binding ElementName= ENV_Password}">
                            <Grid.ColumnDefinitions>                                
                                <ColumnDefinition Width="*" />                              
                            </Grid.ColumnDefinitions>
                            <PasswordBox Tag="" Grid.Column="0" BorderThickness="0" Height="30" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" x:Name="ENV_Password">                                
                                <PasswordBox.Style>

                                </PasswordBox.Style>
                            </PasswordBox>
                        </Grid>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

我添加了 Binding.ValidationRules,它在字段为空时突出显示。现在我必须添加验证来验证连接字符串,如果任何失败都应该突出显示给用户以更改凭据或任何连接字符串参数。我尝试使用 INotifyDataErrorInfo 但无法成功或不知道如何正确使用它。它将整个列表视图突出显示为边框,并且对于有效的连接字符串也保持不变。

我需要向用户突出显示 UI 中有效或无效的连接字符串,而不是突出显示整个列表视图或抛出任何消息框。验证应该在后台发生,而不是通过任何其他事件(如按钮单击等)。这怎么可能正确实现。

4

1 回答 1

0

我发现实现绑定验证的最简单方法是从属性的设置器中抛出异常,然后在 XAML 绑定中实现ValidatesOnExceptions 。

我不知道如何ConnectionString根据您的代码处理或构建您的代码,但如果您认为此方法适合您,这应该会引导您朝着正确的方向前进。在下面的示例中,我ConnectionString在我的模型中构建了我的模型(我假设您已经实现iNotifyPropertyChanged并了解它是如何工作的)。FormatException如果字符串为空,下面的 setter 将抛出 a 。

 private string connectionString;
 public string ConnectionString
 {
        get { return connectionString; }
        set
        {
            if (connectionString != value)
            {
                //Validate String
                if (value == "") 
                { 
                   throw new FormatException("Connection string cannot be empty");
                }    
                connectionString = value;
                NotifyPropertyChanged("ConnectionString");                       
            }
        }
    }

现在假设您将上述连接字符串绑定到 a TextBox,但需要它来验证用户何时删除当前字符串并将其留空。

<TextBox Text="{Binding ConnectionString, UpdateSourceTrigger=LostFocus, Mode=TwoWay, ValidatesOnExceptions=True}"/>

当用户离开 TextBox 时,它会像您想要的那样突出显示,因为设置了 ValidatesOnExceptions。IMO 这个解决方案非常简单,只需要很少的代码。

最后要注意的是,在此示例中,如果您在代码中传递了一个空字符串而不是 UIElement 绑定,则该异常将破坏程序。根据您的示例,我不确定您的计划是什么,但如果字符串仅通过 UIElement 绑定更新,您应该没问题。

于 2018-04-06T15:40:11.000 回答