Я бы советовал абстрагировать форму ввода как отдельную вьюху (если у вас еще не так). Реализуйте интерфейс IDataErrorInfo вашей вьюмоделью.
Пожалуйста, просмотрите это.
Далее - сделайте простой конвертер NonEmptyStringToBooleanConverter и прибиндите его на Enabled свойство кнопки:
<Button Content="Submit" Enabled="{Binding Error, Converter={StaticResource NonEmptyStringToBooleanConverter}" />
Если не понятна идея с NonEmptyStringToBooleanConverter, могу объяснить подробнее.
Как верно заметил @Андрей, можно на кнопку повесить комманду, которая будет изменять "возможноть своего выполнения" (т.е разрешать/запрещать выполнение).
Данное решение использует классы BindableBase и DelegateCommand из библиотеки Prism.Wpf:
public abstract class ValidatableViewModelBase : BindableBase, IDataErrorInfo
{
private readonly DelegateCommand _submitCommand;
private string _error;
public string Error
{
get => _error;
private set
{
if (SetProperty(ref _error, value))
{
_submitCommand.RaiseCanExecuteChanged();
}
}
}
public string this[string columnName] => Error = Validate(columnName);
public ICommand SubmitCommand => _submitCommand;
protected ValidatableViewModelBase()
{
_submitCommand = new DelegateCommand(Submit, () => String.IsNullOrEmpty(Error));
}
protected abstract string Validate(string columnName);
protected abstract void Submit();
}
И тогда вьюха будет выглядеть как:
<TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<TextBlock Text="{Binding Error}" />
<Button Content="Submit" Command="{Binding SubmitCommand}" />
И её вью модель:
public class FormViewModel : ValidatableViewModelBase
{
private string _text;
public string Text
{
get => _text;
set => SetProperty(ref _text, value);
}
protected override string Validate(string columnName)
{
switch (columnName)
{
case nameof(Text):
if (String.IsNullOrEmpty(Text))
{
return "Text can not be empty.";
}
break;
default:
throw new ArgumentOutOfRangeException(nameof(columnName), columnName, null);
}
return String.Empty;
}
protected override void Submit()
{
Debugger.Break();
}
}
И по итогу это будет выглядеть так:

Если Submit необязательный, то можно сделать его виртуальным вместо абстрактного.
CanExecute()? Вместо привязки кEnabled– Андрей NOP Oct 10 '17 at 08:13