这是我的XAML:
<ItemsControl Margin="0 0 0 0" Name="CtrlOrderDetails" AlternationCount="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="Foobar">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="0 5 0 5" FontSize="16" Text="{Binding DrugName}"></TextBlock>
<TextBox Grid.Column="2" FontSize="10" Width="100" Height="20" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalContentAlignment="Center" VerticalAlignment="Center" Tag="{Binding BarCode}"
Text="Enter Barcode.." LostFocus="BarcodeTextBox_OnLostFocus"></TextBox>
<CheckBox x:Name="IsGoodCheckBox" Grid.Column="4" IsEnabled="False" VerticalAlignment="Center"></CheckBox>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="LightGray" TargetName="Foobar"></Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我想要发生的是,当用户在文本框中输入条形码时,如果它与Tag属性中的值匹配,则应将复选框设置为选中。
这是我背后的代码:
private void BarcodeTextBox_OnLostFocus(object sender, RoutedEventArgs e)
{
var tb = sender as TextBox;
ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(CtrlOrderDetails);
DataTemplate yourDataTemplate = contentPresenter.ContentTemplate;
CheckBox thisCheckBox = yourDataTemplate.FindName("IsGoodCheckBox", contentPresenter) as CheckBox;
if (tb.Text == tb.Tag.ToString())
{
thisCheckBox.IsChecked = true;
}
else
{
thisCheckBox.IsChecked = false;
}
}
public TChildItem FindVisualChild<TChildItem>(DependencyObject obj) where TChildItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is TChildItem)
return (TChildItem)child;
var childOfChild = FindVisualChild<TChildItem>(child);
if (childOfChild != null)
return childOfChild;
}
return null;
}
如果我在列表的第一行尝试它,它的效果很好。但是,如果我在第二行尝试它,它会再次影响第一行中的复选框。
显然,我的代码不是我在哪一行。我怎么能这样做?
由于
答案 0 :(得分:1)
试试这个:
private void BarcodeTextBox_OnLostFocus(object sender, RoutedEventArgs e)
{
var tb = sender as TextBox;
Panel grid = tb.Parent as Panel;
if (grid != null)
{
CheckBox checkBox = grid.Children.OfType<CheckBox>().FirstOrDefault(x => x.Name == "IsGoodCheckBox");
if (checkBox != null)
{
//set the IsChecked property based on your logic here...
checkBox.IsChecked = tb.Text == tb.Tag.ToString();
}
}
}
答案 1 :(得分:1)
这将是一种更常规的XAML方式。没有代码,只有绑定和转换器。
<ItemsControl Margin="0 0 0 0" Name="CtrlOrderDetails" AlternationCount="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<local:EqualityMultiConverter
x:Key="EqualityConverter"
/>
</DataTemplate.Resources>
<Grid x:Name="Foobar">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="0 5 0 5" FontSize="16" Text="{Binding DrugName}"></TextBlock>
<TextBox
x:Name="BarCodeTextBox"
Grid.Column="2"
FontSize="10"
Width="100"
Height="20"
HorizontalContentAlignment="Center"
HorizontalAlignment="Center"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
Tag="{Binding BarCode}"
Text="Enter Barcode.."
LostFocus="BarcodeTextBox_OnLostFocus"
/>
<CheckBox
x:Name="IsGoodCheckBox"
Grid.Column="4"
IsEnabled="False"
VerticalAlignment="Center"
>
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource EqualityConverter}">
<Binding Path="BarCode" />
<Binding Path="Text" ElementName="BarCodeTextBox"/>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="LightGray" TargetName="Foobar"></Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Multiconverter类:
public class EqualityMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// Return true if we have fewer than two values,
// or if we have at least two, and they're all equal.
return values.Length < 2 || values.Skip(1).All(v => values[0] == v);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
答案 2 :(得分:0)
您的代码每次都找到相同的CheckBox,因为您可以按名称定义它。相反,你应该看一个控件类型。
根据another question的回答,您可以尝试这样的事情:
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}