Первоначально при запуске TextBox пустой, если я начинаю в нем что то печатать, а потом удаляю все, чтобы он был пустой, то появляется ошибка валидации. Но мне бы хотелось, чтобы эта ошибка появлялась и при нажатии на кнопку (если в TextBox совсем ничего не было напичатано). Мне не понятно, что нужно написать в Command или CanExecute, чтобы заставить TextBox запустить валидацию.
<UserControl x:Class="ExpenseTracker.Views.AccountsView"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:validationRules="clr-namespace:ExpenseTracker.ValidationResultRules">
<StackPanel>
<TextBox x:Name="accountName">
<TextBox.Text>
<Binding Path="Input"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validationRules:NotEmpty></validationRules:NotEmpty>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Grid.Row="4" Grid.Column="2"
Command="{Binding AddAccountCommand}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=accountName}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style> Add Account
</Button>
</StackPanel>
internal sealed class NotEmpty :ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
ValidationResult result = ValidationResult.ValidResult;
if(((string)value).Length==0)
{
result = new ValidationResult(false, "String is empty");
}
return result;
}
}
На самом деле использовать ValidationRule
в MVVM неправильно, потому что это всё-таки вьюшная валидация и VM о ней ничего не знает. Вам же нужна валидация в VM, которая реализуется с помощью интерфейсов IDataErrorInfo
/INotifyDataErrorInfo
(см. этот ответ на enSO).
"Малой кровью" вашу задачу можно решить включив в правиле валидации ValidatesOnTargetUpdated
:
...
<validationRules:NotEmpty ValidatesOnTargetUpdated="True"/>
...
В правиле валидации только измените условие на такое (может ведь и null придти):
...
if (string.IsNullOrEmpty((string)value))
...
Тогда ваш TextBox будет красным прямо при запуске
Еще вариант (который я нашел здесь), написать такой класс для принудительной валидации:
public static class Validator
{
/// <summary>
/// This method forces WPF to validate the child controls of the control passed in as a parameter.
/// </summary>
/// <param name="parent">Type: DependencyObject. The control which is the descendent root control to validate.</param>
/// <returns>Type: bool. The validation result</returns>
public static bool IsValid(DependencyObject parent)
{
// Validate all the bindings on the parent
bool valid = true;
LocalValueEnumerator localValues = parent.GetLocalValueEnumerator();
while (localValues.MoveNext())
{
LocalValueEntry entry = localValues.Current;
if (BindingOperations.IsDataBound(parent, entry.Property))
{
Binding binding = BindingOperations.GetBinding(parent, entry.Property);
foreach (ValidationRule rule in binding.ValidationRules)
{
ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null);
if (!result.IsValid)
{
BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null));
valid = false;
}
}
}
}
// Validate all the bindings on the children
for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (!IsValid(child))
{
valid = false;
}
}
return valid;
}
}
И использовать его, например, при загрузке окна:
Loaded += (s, e) => Validator.IsValid(this);
Или в обработчике клика по кнопке.
Правда, как взаимодействовать с ним из VM я не знаю (почему — см. первый абзац ответа).
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
На данный вопрос уже ответили:
Всем добрый деньПытаюсь отправить AJAX форму на сервер, но метод контроллера, которым должна обрабатываться форма, не вызывается
Мне нужно отслеживать свайп пальцем на "Unity c#"Мне надо чтобы когда игрок делал свайп по экрану, игровая камера двигалась по карте, но не выходила...