Как правило, чтобы выполнить то, что вы ищете, вы используете шаблон типа MVVM.Это означает, что вы привязываете каждый элемент управления, который собирает данные в вашей форме WPF, к вспомогательному полю или свойству.Вы добавляете проверку в привязку со стилем, который вызовет красную рамку.Для элементов управления с необходимыми данными часть проверки заключается в том, что они заполнены. Вы можете определить одно правило проверки для этого, называемое «ValidWhenHasData» или что-то подобное.
Чтобы заставить проверки срабатывать только при нажатии«сохранить» или тому подобное, есть несколько способов сделать это.Я обычно делаю свойство в каждом правиле проверки с именем «IsEnabled» и по умолчанию устанавливаю его в false;если установлено значение false, правило проверки всегда возвращает действительное.Затем я добавляю в код позади элементов управления, которые я хочу проверить.Когда нажата кнопка «сохранить», я просматриваю список и устанавливаю для всех правил проверки IsEnabled значение true, очищаю все ошибки в элементах управления в списке и затем обновляю привязку для каждого из них.Это отобразит красные прямоугольники на тех, которые не заполнены, или на том, что вы определили как условие ошибки.Вы также можете использовать этот список, чтобы установить фокус на первый элемент управления, который не прошел проверку, в выбранном вами порядке.
Пример шаблона элемента управления проверкой, который содержит заполнитель для всплывающей подсказки об ошибке проверки:
<ControlTemplate x:Key="errorTemplate">
<Canvas Width="{Binding Path=AdornedElement.ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}" Height="{Binding Path=AdornedElement.ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}">
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder/>
</Border>
<Border Canvas.Top="-5" Canvas.Right="-5" BorderBrush="Gray" BorderThickness="1" >
<TextBlock x:Name="errorBlock" TextAlignment="Center" Background="Red" Foreground="White" Width="10" Height="10" FontSize="9" ctl:valTooltip.MessageBody="{Binding Path=AdornedElement.(Validation.Errors)[0].ErrorContent,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}">*</TextBlock>
</Border>
</Canvas>
</ControlTemplate>
Пример привязки проверки:
<TextBox x:Name="TBNumItems" Margin="2,2,2,2" MinWidth="40" HorizontalAlignment="Left" Validation.ErrorTemplate="{StaticResource errorTemplate}">
<TextBox.Text>
<Binding x:Name="NumItemsBinding" Path="NumItems" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<cal:UIntValidationRule x:Name="NumItemsValidationRule" MinValue="1" MaxValue="99999" IsEnabled="False"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Пример кода для проверки:
/// <summary>
/// Clears all validation errors
/// </summary>
void ClearAllValidationErrors()
{
Validation.ClearInvalid(TBNumItems.GetBindingExpression(TextBox.TextProperty));
}
/// <summary>
/// Revalidates everything
/// </summary>
void RevalidateAll()
{
ClearAllValidationErrors();
TBNumItems.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}