Проверка текстового поля WPF не запускается после изменения содержимого - PullRequest
0 голосов
/ 08 апреля 2019

Я пытаюсь проверить текстовое поле в приложении 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 - единственное с проверкой на данный момент.

1 Ответ

0 голосов
/ 08 апреля 2019
<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"
                 NotifyOnValidationError="True"
                 ValidatesOnNotifyDataErrors="True">
            <Binding.ValidationRules>
                <local:ValRule ValidatesOnTargetUpdated="True"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

NotifyOnValidationError и ValidatesOnNotifyDataErrors должны сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...