Question

i have a LongListSelector in windows phone 8, i wanna bind two ObservableCollections to the LongListSelector. the Question is how do i support multi binding in LongListSelector

search on the internet... someone suggests CompositeCollection, windows phone dev env cannot identify CompositeCollection, does windows phone support CompositeCollection?

<phone:LongListSelector 
                    x:Name="articleList"
                    Grid.Row="1"   
                    Margin="0,0,-12,0" 
                    DataContext="{StaticResource viewModel}"
                    ItemTemplate="{StaticResource ResultItemTemplate}"   
                    ItemsSource="{Binding ArticleCollection}"
                    ItemRealized="articleList_ItemRealized"
                    SelectionChanged="LongListSelector_SelectionChanged"

                    >


<DataTemplate x:Key="ResultItemTemplate">
            <Grid Margin="0,6,0,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Rectangle Fill="Gray" Height="50" Width="50" Grid.Row="0" Grid.Column="0" 
                         VerticalAlignment="Top" Margin="0,7,7,0"
                       Grid.RowSpan="2">

                </Rectangle>
                <Image Source="{Binding ImageUriCollection.ImageSource}" Height="50" Width="50" Grid.Row="0" Grid.Column="0" 
                         VerticalAlignment="Top" Margin="0,7,7,0"
                       Grid.RowSpan="2">

                    <!--
                    <Image.Source>
                        <BitmapImage UriSource="{Binding Path= ImageUriCollection.ImageSource, Mode=TwoWay}"
                                     CreateOptions="BackgroundCreation"/>
                    </Image.Source>
                    -->
                </Image>
                <TextBlock Text="{Binding Path=Subject, Mode=TwoWay}" Grid.Row="0" Grid.Column="1"
                                 Foreground="{StaticResource PhoneAccentBrush}" VerticalAlignment="Top"/>

                <TextBlock Text="{Binding Path=Words, Mode=TwoWay}" TextWrapping="Wrap"
                               Grid.Row="1" Grid.Column="1"
                               VerticalAlignment="Top"
                               />

            </Grid>
        </DataTemplate>

code behind in viewmodel is

public ObservableCollection<Article> ArticleCollection
        {
            get;
            private set;
        }

        public ObservableCollection<Photo> ImageUriCollection
        {
            get;
            private set;
        }

model is

public class Article : INotifyPropertyChanged
    {
        private int _Id;
        public int ID
        {
            get { return _Id; }
            set
            {
                if (_Id != value)
                {
                    _Id = value;
                    NotifyPropertyChanged();
                }
            }
        }


        private string _subject;
        public string Subject
        {
            get
            {
                return _subject;
            }
            set
            {
                if (_subject != value)
                {
                    _subject = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private string _words;
        public string Words
        {
            get
            {
                return _words;
            }
            set
            {
                if (_words != value)
                {
                    _words = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private DateTime _publishDate;
        public DateTime PublishDate
        {
            get
            { return _publishDate; }
            set
            {
                if (_publishDate != value)
                {
                    _publishDate = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private string _imagePath;
        public string ImagePath
        {
            get { return _imagePath; }
            set
            {
                if (_imagePath != value)
                {
                    _imagePath = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


public class Photo
    {
        public string Title { get; set; }
        public Uri ImageSource { get; set; }
        public DateTime TimeStamp { get; set; }
    }
Was it helpful?

Solution

It is like @venerik said - CompositeCollection is not available on Windows Phone.

But my proposal is to write your own Composite class. I've managed to build a simple example:

In XAML: - simple ListBox (of course it can be LLS)

<Grid x:Name="LayoutRoot" Background="Transparent">       
    <ListBox Name="myList" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

In code behind: - custom class

public class myComposite<T> : ICollection<T>
{
    ObservableCollection<T> firstCollection;
    ObservableCollection<T> secondCollection;

    public myComposite(ObservableCollection<T> first, ObservableCollection<T> second)
    {
        firstCollection = first;
        secondCollection = second;
    }

    IEnumerator IEnumerable.GetEnumerator() { return new myEnum<T>(this); }
    public IEnumerator<T> GetEnumerator() { return new myEnum<T>(this); }

    public int Count { get { return firstCollection.Count + secondCollection.Count; } }
    public T this[int i]
    {
        get
        {
            if (i <= firstCollection.Count - 1) return firstCollection[i];
            else return secondCollection[i - firstCollection.Count];
        }
        set
        {
            if (i <= firstCollection.Count - 1) firstCollection[i] = value;
            else secondCollection[i - firstCollection.Count - 1] = value;
        }
    }

    public void Add(T item) { throw new NotImplementedException(); }
    public void Clear() { throw new NotImplementedException(); }
    public bool Contains(T item) { throw new NotImplementedException(); }
    public void CopyTo(T[] array, int arrayIndex) { throw new NotImplementedException(); }
    public bool IsReadOnly { get { throw new NotImplementedException(); } }
    public bool Remove(T item) { throw new NotImplementedException(); }

    private class myEnum<T> : IEnumerator<T>
    {
        public myComposite<T> _items;
        int position = -1;

        public myEnum(myComposite<T> list) { _items = list; }

        public bool MoveNext()
        {
            position++;
            return (position < _items.Count);
        }

        public void Reset() { position = -1; }

        object IEnumerator.Current { get { return Current; } }

        public T Current
        {
            get
            {
                try { return _items[position]; }
                catch (IndexOutOfRangeException)
                { throw new InvalidOperationException(); }
            }
        }

        public void Dispose() { }
    }
}

And MainPage: - for test

public partial class MainPage : PhoneApplicationPage
{
    ObservableCollection<string> listOne = new ObservableCollection<string>();
    ObservableCollection<string> listTwo = new ObservableCollection<string>();

    myComposite<string> composite;
    public myComposite<string> Composite
    {
        get { return composite; }
        set { composite = value; }
    }

    public MainPage()
    {
        InitializeComponent();

        listOne.Add("First");
        listOne.Add("Second");
        listOne.Add("Third");
        listTwo.Add("Fourth");
        composite = new myComposite<string>(listOne, listTwo);
        myList.ItemsSource = Composite;
    }
}

Note that this is only a very basic example - it lacks INotifyPropertyChanged and most of methods that should be implemented. But hopefully it will show you how it works.

And of course all collections must have items of the same type.

OTHER TIPS

I don't think CompositeCollection is available on Windows Phone and I don't think it is suitable for your problem either. A CompositeCollection can be used to join multiple collections. For instance if you have list containing 5 vegetables and a list containing 3 fruits you could join them to display a list of 8 items.

In your case, I think, you want to join the articles and the photo's to become one item. Why don't you add a Photo property to your Article class?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top