Проверка данных элемента WPF ListView

Мне нужно иметь список строк подключения, который пользователь будет периодически добавлять / редактировать. Поэтому я настроил представление списка, которое связывает данные с наблюдаемой коллекцией.

<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, но не смог или не знаю, как правильно его использовать. Он выделяет весь список в виде границы и остается неизменным и для действительной строки подключения.

Мне нужно выделить пользователю, которые являются действительными или недопустимыми строками подключения в пользовательском интерфейсе, а не выделить весь вид списка или выбросить какие-либо окна сообщений. Проверка должна происходить в фоновом режиме, а не какими-либо другими событиями (такими как нажатие кнопки и т. Д.). Как это могло быть правильно достигнуто.

1 ответ

Я обнаружил, что самый простой способ реализовать проверки привязки - это выбросить исключения из установщиков вашего свойства и затем реализовать исключения ValidatesOnException в привязках XAML.

Я не знаю как твои ConnectionString обрабатывается или строится на основе вашего кода, но это должно привести вас в правильном направлении, если вы решите, что этот метод работает для вас. В приведенном ниже примере я строю свой ConnectionString в моей модели (я предполагаю, что вы уже реализовали iNotifyPropertyChanged и понять как это работает). Ниже сеттер бросит FormatException если строка пуста

 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");                       
            }
        }
    }

Теперь давайте предположим, что вы связали вышеуказанную строку подключения с TextBox, но нужно проверить, когда пользователь удаляет текущую строку и оставляет ее пустой.

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

Когда пользователь покидает TextBox, он будет выделяться так, как вы хотите, потому что ValidatesOnExceptions установлен. ИМО это решение очень простое и требует мало кода.

Последнее, на что следует обратить внимание, это то, что в этом примере, если вы передали пустую строку в коде вместо привязки UIElement, исключение нарушит работу программы. Исходя из вашего примера, я не уверен точно, что вы планируете, но если строки обновляются только через привязки UIElement, у вас все должно быть в порядке.

Другие вопросы по тегам