Foreach只适用于ListBox的第一项

本文关键字:一项 适用于 ListBox Foreach | 更新日期: 2023-09-27 18:27:21

我的Windows Phone应用程序有一个由JSON填充的ListBox。在我填充了ListBox之后,我需要比较用户键入的(字符串)是否存在于ListBox中。因此,ListBox上的每一项都有来自一个集合的3个信息。我只需要将集合中的一项与字符串进行比较。

我有一些代码,但这只适用于ListBox的第一项:

private void addProduto(object sender, RoutedEventArgs e)
{            
    Fields fi = (Fields)this.List1.SelectedItem as Fields;
    foreach(var item in List1.Items)
    {
        Fields fields = item as Fields;
        if (fields.codigo == insCodProduto.Text)
        {
            MessageBox.Show("this product exists!");
            break;
        }
        else
        {
            MessageBox.Show("this product not exists");
            break;
        }
    }
}

收藏:

public ObservableCollection<Fields> Items { get; set; }
public class Fields
{
    public string descricao { get; set; }
    public double valor_preco_a { get; set; }
    public string codigo { get; set; }
    public string codigo1 { get; set; }
    public string descricao1 { get; set; }
}

列表框:

<ListBox Name="List1" ItemsSource="{Binding Items}" Margin="0,85,0,0" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="242" />
                    <ColumnDefinition Width="128" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <StackPanel Hold="addToList2" Margin="0,0,-62,17" Grid.ColumnSpan="3">
                    <StackPanel.Background>
                        <SolidColorBrush Color="#FF858585" Opacity="0.5"/>
                    </StackPanel.Background>
                    <TextBlock x:Name="NameTxt" Grid.Column="0" Text="{Binding descricao}" TextWrapping="Wrap" FontSize="20" Style="{StaticResource PhoneTextNormalStyle}"/>
                    <TextBlock Grid.Column="1" Text="{Binding valor_preco_a, StringFormat=N2}" TextWrapping="Wrap" Margin="45,20,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
                    <TextBlock Grid.Column="3" Text="{Binding codigo}" TextWrapping="Wrap" FontSize="35" Margin="370,-50,12,0" Style="{StaticResource PhoneTextNormalStyle}" Foreground="Blue"/>
                </StackPanel>
                <TextBlock Grid.Column="0" Text="R$" Margin="15,48,158,17" Style="{StaticResource PhoneTextSubtleStyle}"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

Foreach只适用于ListBox的第一项

由于break语句,您的foreach只检查第一个值。此外,循环需要检查值是否匹配,但只有在循环结束后才能知道是否没有匹配。所以你需要这样的东西。

bool found = false;
foreach(Fields fields in List1.Items)
{
    if (fields.codigo == insCodProduto.Text)
    {
        MessageBox.Show("this product exists!");
        found = true;
        break;
    }
}
if(!found)
{
    MessageBox.Show("this product not exists");
}

还要注意,如果您在foreach中指定类型,它将为您执行强制转换。

vallabha的答案是完全正确的。然而,还有另一种可能更容易的解决方案来检查是否存在包含用户键入内容的项目。您可以使用枚举。任何<TSource>方法

在你的代码中,这将变成:

var isInListBox = List1.Items.Cast<Fields>().Any(x => x.codigo == insCodProduto.Text);
if (isInListBox)
{
    MessageBox.Show("This product exists!");
}
else
{
    MessageBox.Show("This product doesn't exist.");
}

使用这种方法的优点如下(来自MSDN):

一旦可以确定结果,就停止对源的枚举。

您可以使用LINQ缩短代码以检查是否存在任何匹配:

if (List1.Items.Cast<Fields>().Any(f => f.codigo == insCodProduto.Text))
    MessageBox.Show("this product exists!");
else
    MessageBox.Show("this product not exists");

它将具有与您试图实现的代码相同的效果,因为当找到匹配时,Any()将停止查看集合(并返回True)。否则返回False

当您在第一次迭代后在foreach循环中使用break时,它将打破foreach循环