Проверка данных элемента 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, у вас все должно быть в порядке.