Ручной анализ элементов управления в приложении WPF является антипаттерном.
WPF предоставляет более эффективные способы достижения того, что вам нужно, с помощью привязок и шаблонов .
Вы можете использовать Style
на каждом TextBox
, чтобы WPF автоматически изменил свойство BorderBrush
в зависимости от результата равенства между свойством Text
и значением DataContext
(которое кажется быть типом string
в вашем случае).
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.Resources>
<local:EqualityConverter x:Key="EqualityConverter"/>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="8*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding .}" />
<TextBox x:Name="textBox" Grid.Column="1">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="BorderBrush" Value="Red" /> <!-- Default color -->
<Style.Triggers>
<DataTrigger Value="true">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource EqualityConverter}">
<Binding RelativeSource="{RelativeSource Mode=Self}" Path="Text"/>
<Binding Path="."/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="BorderBrush" Value="Green" /> <!-- Color when values are equal -->
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Вам необходимо определить дополнительный фрагмент кода (a Converter
):
/// <summary>
/// Returns true if all passed values are equal.
/// </summary>
public class EqualityConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
=> values.All(v => v.Equals(values[0]));
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
Устранение проблемы WPF-ориентированным способом
Еще лучший способ достичь желаемого - определить правильную модель вида с самого начала:
public class QuestionViewModel {
public string RequiredText { get; set; }
public string InputText{ get; set; }
public bool IsCorrect => RequiredText.Equals(InputText);
}
(Это должно реализовать INotifyPropertyChanged
, но для простоты я не показал этого)
И вы бы связали свой ItemsControl.ItemsSource
с набором QuestionViewModel
вместо набора string
:
<ItemsControl ItemsSource="{Binding Questions}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="8*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding RequiredText}" />
<TextBox x:Name="textBox" Grid.Column="1" Text="{Binding InputText}">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="BorderBrush" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsCorrect}" Value="true">
<Setter Property="BorderBrush" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Вероятно, вам следует взглянуть на шаблон MVVM.