Я пытаюсь проверить текстовое поле в приложении WPF, которое использует и текстовые поля, и DataGrid.
Проверка запускается при загрузке - показывает, что текстовое поле пусто.Но когда я на самом деле набираю что-то в текстовое поле, а затем перехожу в другое, оно все равно отображается как недействительное - проверка не запускается снова.
И сетка данных, и текстовые поля используют привязку данных для загрузкии записи данных из базы данных.
Я создал правило проверки на основе этого учебника: https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-binding-validation.
И в основном это решение работает для меня - когда я сначала выбираю строку в сетке данных, а затем запускаюизменение содержимого текстовых полей - проверка работоспособности.Однако, как упоминалось ранее - он не работает должным образом, когда приложение запускается и ничего не выбрано (и текстовые поля пусты).
Ниже фрагменты моего XAML файла:
<Window.Resources>
<CollectionViewSource x:Key="printLogViewSource" d:DesignSource="{d:DesignInstance {x:Type local:PrintLog}, CreateList=True}" >
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Name"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
</Window.Resources>
<Grid Background="#FFE5E5E5" Width="Auto" DataContext="{StaticResource printLogViewSource}">
<GroupBox x:Name="groupBox" Header="Add/Update/Remove" Margin="10,573,10,15">
<Grid Margin="0,0,0,0">
<Grid x:Name="grid1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Name:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="nameTextBox" Validation.ErrorTemplate="{StaticResource validationTemplate}" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" VerticalAlignment="Center" Width="120" AutomationProperties.IsRequiredForForm="True">
<TextBox.Text>
<Binding Path="Name"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:ValRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
<Grid x:Name="grid2" HorizontalAlignment="Left" Margin="191,10,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Person:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="personTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Person, Mode=OneWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=Explicit}" VerticalAlignment="Center" Width="120"/>
</Grid>
</Grid>
</GroupBox>
<DataGrid x:Name="printLogDataGrid" AutoGenerateColumns="False" IsReadOnly="True" EnableRowVirtualization="True" ItemsSource="{Binding Source={StaticResource printLogViewSource}, UpdateSourceTrigger=PropertyChanged}" Margin="10,10,10,141" RowDetailsVisibilityMode="VisibleWhenSelected" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn x:Name="printIDColumn" Binding="{Binding PrintID}" Header="Print ID" Width="Auto" IsReadOnly="True"/>
<DataGridTextColumn x:Name="nameColumn" Binding="{Binding Name}" Header="Name" Width="Auto"/>
<DataGridTextColumn x:Name="personColumn" Binding="{Binding Person}" Header="Person" Width="Auto"/>
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<DataGridCell Content="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
</Grid>
Вот мой ValidationRule :
class ValRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if ((string)value == "")
{
return new ValidationResult(false, "Field cannot be empty");
}
else
{
return ValidationResult.ValidResult;
}
}
}
А вот фрагмент моего MainWindow.xaml.cs :
public partial class MainWindow : Window
{
private printDBEntities _context = new printDBEntities();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_context.PrintLogs.Load();
System.Windows.Data.CollectionViewSource printLogViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("printLogViewSource")));
printLogViewSource.Source = _context.PrintLogs.Local;
printLogDataGrid.SelectedIndex = -1;
//I'm setting this value to -1 so that on load my TextBoxes are empty.
//If i don't add this, on load my textboxes have value corrseponding to first row of datagrid.
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
this._context.Dispose();
}
//Below normally are functions responsible for Add/Update/Remove buttons
}
Может ли строка printLogDataGrid.SelectedIndex = -1;
при загрузке окна частично отвечать за эту проблему?Как упомянуто в коде - если я пропущу это, первая строка сетки данных будет выбрана при запуске, что означает, что текстовые поля также заполняются данными при запуске - это будет означать, что пользователю придется удалять текст из каждого поля, чтобы добавить новыйзапись.
РЕДАКТИРОВАТЬ
Чтобы прояснить ситуацию - текстовое поле, которое не работает должным образом, является nameTextBox - единственное с проверкой на данный момент.