【问题标题】:Windows Phone 7 - App.ViewModel duplicatesWindows Phone 7 - App.ViewModel 重复
【发布时间】:2011-02-03 01:11:44
【问题描述】:
App.ViewModel.RefreshItems();
lbFruit.ItemsSource = App.ViewModel.ItemCollection;

我在 ItemsCollection 中有重复项。在我的列表框中,我只想显示唯一值。我如何才能抓住那些展示?

我需要在这里显示更多数据...

在我的集合中,我有一组数据,其中可能包含集合中某些属性的重复项..

在我的视图模型中,假设我有水果和蔬菜作为属性。

我可以:

ItemCollection[0].fruit = "苹果" ItemCollection[0].vegetable="胡萝卜"

ItemCollection[1].fruit = "梨" ItemColection[1].vegetable="胡萝卜"

ItemCollection[2].fruit = "苹果" itemCollection[2].vegetable = "绿豆"

如果我只想显示我收藏中的水果列表,我将如何在不重复的情况下做到这一点?

例如,我的收藏中可能有多种水果和多种蔬菜。如果我只在列表中显示水果,我怎么能只显示:Apple、Pear、Orange

更多代码:

当我按照以下建议执行不同操作时: lbFruit.ItemsSource = App.ViewModel.ItemCollection.Select(item => item.fruit).Distinct();

我得到 2 个 *(* 是列表的项目符号,在 DataTemplate 的 TextBlock 中找到)。

所以从技术上讲,Distinct 是有效的,但文本没有显示在 * 旁边。 如您所见,还有一个我在原始示例中没有显示的 ProductNumber。但是,当我删除它时,我仍然得到相同的 2 个 *。

我需要在 XAML 方面做些什么来使不同的工作有效吗?另外,如果我想显示产品编号,我该如何将其添加到上面的 Select 中(如果我们可以让它工作)?

           <ListBox x:Name="lbFruit" ItemsSource="{Binding ItemCollection}" SelectionChanged="lbFruit_SelectionChanged">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel x:Name="DataTemplateStackPanel" Orientation="Horizontal">
                            <TextBlock FontFamily="Segoe WP Semibold" FontWeight="Bold" FontSize="30" VerticalAlignment="Top" Margin="20,10">*</TextBlock>
                            <StackPanel>
                                <TextBlock x:Name="ItemText" Text="{Binding Fruit}"  FontSize="{StaticResource PhoneFontSizeLarge}"/>
                                <TextBlock x:Name="ItemNumber" Text="{Binding ProductNumber}"  FontSize="{StaticResource PhoneFontSizeNormal}"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

希望这一切都有意义...感谢所有帮助!

【问题讨论】:

  • 使用扩展方法如.Distinct();
  • @lukas - 我试过了,但没有运气......绑定仍然显示重复的值。

标签: c# silverlight linq windows-phone-7


【解决方案1】:

这个怎么样:

lbFruit.ItemsSource = App.ViewModel.ItemCollection.Select(item => item.fruit).Distinct();

编辑:

以上代码不适用于您的情况,因为它返回的是String 值列表,而不是您的项目。

要解决这个问题,您需要在Distinct() 中使用IEqualityComparer&lt;T&gt;

你没有提到你的类名或定义,所以,对于下面的定义,

public class ProductItem
{
    public int ProductNumber { get; set; }
    public String Fruit { get; set; }
    public String Vegetable { get; set; }
}

您需要创建一个IEqualityComparer&lt;ProductItem&gt;,如下所示:

public class ProductItemByFruitComparer : IEqualityComparer<ProductItem>
{
    public bool Equals(ProductItem x, ProductItem y)
    {
        // Case-insensitive comparison of Fruit property of both objects evaluates equality between them
        return x.Fruit.Equals(y.Fruit, StringComparison.CurrentCultureIgnoreCase);
    }

    public int GetHashCode(ProductItem obj)
    {
        // Since we are using Fruit property to compare two ProductItems, we return Fruit's HashCode in this method
        return obj.Fruit.GetHashCode();
    }
}

然后,下面的语句应该可以解决问题:

lbFruit.ItemsSource = App.ViewModel.ItemCollection.Distinct(new ProductItemByFruitComparer());

【讨论】:

  • 当我这样做时,绑定不会发生,或者至少 ItemCollection 中的文本不会显示(在列表框中)。有什么想法吗?
  • 我添加了更多代码,看看是否需要在 xaml 中做一些不同的事情...
  • !你摇滚!这就像一个冠军......只是出于好奇......如果我想进一步探索你是如何想出这个解决方案的,是否有一些网站可以让我看看 HashCode 是什么以及你为什么使用它?或有关 IEqualityComparer 的更多信息?我不想只是问这些问题而不试图更好地理解它们。再次感谢!
猜你喜欢
  • 2012-03-18
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多