Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the LongListSelector add extra items if the collection values are identical?

I noticed this strange behavior yesterday when putting together a demo application for WP. Usually I never pass in plain items, and never the ‘same’- but this time I did. When bound to an observablecollection of type int or string, if the value is the same, the control will add first one item, then two, then three, then four. Instead of adding one each time. Basically it does this:

Items.Count ++

If I however change the item, say string, to something unique (a GUID.ToString for example) it has the expected behavior.

This is regardless of how the DataContext is set, or if I add LayoutMode="List" IsGroupingEnabled="False" to the control.

Why does it do this? And is this expected behavior?

I spent hours searching for an answer, so please don’t just paste random links about the control :)

Code for the view:

<phone:PhoneApplicationPage
x:Class="Bug.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
DataContext="{Binding RelativeSource={RelativeSource Self}}">

<StackPanel>
    <Button Click="Button_Click">Add</Button>
    <phone:LongListSelector  Width="300" Height="600" ItemsSource="{Binding Items}"/>
</StackPanel>
</phone:PhoneApplicationPage>

Code behind:

using System.Collections.ObjectModel;
using System.Windows;


namespace Bug
{
    public partial class MainPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            Items = new ObservableCollection<string>();

            //DataContext = this;
        }

        public ObservableCollection<string> Items { get; set; }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Items.Add("A");

            // This works as expected
            //Items.Add(Guid.NewGuid().ToString());
        }
    }

}
like image 492
Iris Classon Avatar asked Nov 10 '22 10:11

Iris Classon


1 Answers

This is a bug in LongListSelector. The reason it works with Guid is because this'll do a reference comparison and avoid the bug.

Here's a workaround by using a reference object instead:

public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Sample code to localize the ApplicationBar
        Items = new ObservableCollection<Object>();

    }
    public ObservableCollection<Object> Items { get; set; }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Items.Add(new Object() { Value = "A" });

        // This works as expected
        //Items.Add(Guid.NewGuid().ToString());
    }

}
public class Object
{
    public string Value { get; set; }

    public override string ToString()
    {
        return Value;
    }
}
like image 153
dotMorten Avatar answered Nov 14 '22 21:11

dotMorten