如何在WP8中进行CompositeCollection?

时间:2014-02-12 03:14:46

标签: c# windows-phone-7 data-binding windows-phone-8 longlistselector

我在Windows Phone 8中有一个LongListSelector,我想将两个ObservableCollections绑定到LongListSelector。问题是我如何支持LongListSelector中的多重绑定

在互联网上搜索...有人建议使用CompositeCollection,windows phone dev env无法识别CompositeCollection,windows phone是否支持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>

viewmodel中的代码是

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

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

模型是

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; }
    }

2 个答案:

答案 0 :(得分:0)

我不认为CompositeCollection在Windows Phone上可用,我认为它也不适合您的问题。 CompositeCollection可用于连接多个集合。例如,如果您有包含5个蔬菜的列表和包含3个水果的列表,您可以加入它们以显示8个项目的列表。

在你的情况下,我想,你想加入文章和照片成为一个项目。为什么不在Article类中添加Photo属性?

答案 1 :(得分:0)

就像@venerik said - CompositeCollection在Windows Phone上不可用。

但我的建议是编写自己的Composite类。我已成功构建a simple example

在XAML中: - 简单的ListBox(当然它可以是LLS)

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

在代码背后: - 自定义类

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() { }
    }
}

和MainPage: - 进行测试

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;
    }
}

请注意,这只是一个非常基本的示例 - 它缺少INotifyPropertyChanged和大多数应该实现的方法。但希望它会告诉你它是如何工作的。

当然,所有收藏品必须包含相同类型的物品。