Я создал два элемента UserControl, A и B. A имеет текстовое поле, текст которого привязан к целочисленному свойству UserControl, а A также имеет общедоступное свойство зависимости только для чтения HasError
. Я получаю сообщение об ошибке, говорящее, что Validation.HasError
не может быть привязан к данным, поэтому я обновляю это свойство вручную в обработчике событий с измененным текстом. Я создал и включил свойство Integer
, чтобы я мог ввести «xx» в текстовое поле и сделать Validation.HasError
истинным. Все с рабочей проверкой будет работать так же.
В общем родителе я связываю A.HasError с B.IsEnabled через преобразователь логического отрицания. Я мог бы написать триггер, как и ваш Преимущество этого подхода, в дополнение к тому, что он работает, состоит в том, что двум элементам управления UserControl не нужно знать о внутренностях друг друга, и ни один из них не зависит от другого. Кроме того, если вы хотите создать девять из этих пар в ItemTemplate ListBox, вы можете сделать это без каких-либо проблем.
A.xaml
<TextBox
VerticalAlignment="Top"
TextChanged="IntegerTextBox_TextChanged"
Text="{Binding Integer, RelativeSource={RelativeSource AncestorType=UserControl}, UpdateSourceTrigger=PropertyChanged}"
/>
A.xaml.cs
private void IntegerTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
HasError = Validation.GetHasError(sender as TextBox);
}
public bool HasError
{
get { return (bool)GetValue(HasErrorProperty); }
protected set { SetValue(HasErrorPropertyKey, value); }
}
internal static readonly DependencyPropertyKey HasErrorPropertyKey =
DependencyProperty.RegisterReadOnly(nameof(HasError), typeof(bool), typeof(A),
new PropertyMetadata(false));
public static readonly DependencyProperty HasErrorProperty =
HasErrorPropertyKey.DependencyProperty;
public int Integer
{
get { return (int)GetValue(IntegerProperty); }
set { SetValue(IntegerProperty, value); }
}
public static readonly DependencyProperty IntegerProperty =
DependencyProperty.Register(nameof(Integer), typeof(int), typeof(A),
new PropertyMetadata(0));
MainWindow.xaml
<Window.Resources>
<local:NotConverter x:Key="Not" />
</Window.Resources>
<Grid>
<StackPanel>
<local:A
Integer="34"
x:Name="MyAInstance"
/>
<local:B
IsEnabled="{Binding HasError, ElementName=MyAInstance,
Converter={StaticResource Not}}"
/>
</StackPanel>
</Grid>
MainWindow.xaml.cs
public class NotConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return !System.Convert.ToBoolean(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return !System.Convert.ToBoolean(value);
}
}