如何在WP8中做一个CompositeCollection? [英] how to do a CompositeCollection in WP8?

查看:200
本文介绍了如何在WP8中做一个CompositeCollection?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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>
<网格边距=0,6,0,0>
< Grid.RowDefinitions>
< RowDefinition Height =Auto/>
< RowDefinition Height =*/>
< /Grid.RowDefinitions>
< Grid.ColumnDefinitions>
< ColumnDefinition Width =Auto/>
< ColumnDefinition Width =*/>
< /Grid.ColumnDefinitions>
< Rectangle Fill =GrayHeight =50Width =50Grid.Row =0Grid.Column =0
VerticalAlignment =TopMargin =0, 7,7,0
Grid.RowSpan =2>

< / Rectangle>
< Image Source ={Binding ImageUriCollection.ImageSource}Height =50Width =50Grid.Row =0Grid.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 =0Grid.Column =1
Foreground ={StaticResource PhoneAccentBrush}VerticalAlignment =顶部/>

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

< / Grid>
< / DataTemplate>

viewmodel中的代码是

  public ObservableCollection< Article> ArticleCollection 
{
get;
私人集;
}

public ObservableCollection< Photo> ImageUriCollection
{
get;
私人集;
}

模型是

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


私人字符串_subject;
public string Subject
{
get
{
return _subject;
}
set
{
if(_subject!= value)
{
_subject = value;
NotifyPropertyChanged();
}
}
}

私人字符串_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();
}
}
}

私人字符串_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;组; }
public Uri ImageSource {get;组; }
public DateTime TimeStamp {get;组; }
}


解决方案

href =http://stackoverflow.com/a/21721310/2681948> @venerik说 - CompositeCollection 在Windows Phone上不可用。



但我的建议是编写自己的Composite类。我设法构建了一个简单的例子



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

 < Grid x:Name =LayoutRoot 透明> 
< ListBox Name =myList>
< ListBox.ItemTemplate>
< DataTemplate>
< TextBlock Text ={Binding}/>
< / DataTemplate>
< /ListBox.ItemTemplate>
< / ListBox>
< / Grid>

在代码背后: - 自定义类

  public class myComposite< T> :ICollection< T> 
{
ObservableCollection< T>第一收
ObservableCollection< T>第二收

public myComposite(ObservableCollection< T> first,ObservableCollection< T>第二)
{
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; }

对象IEnumerator.Current {get {return Current; }}

public T当前
{
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>综合;
public myComposite< string>复合
{
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和大多数应该实现的方法。但是希望它会告诉你它是如何工作的。



当然,所有的集合必须具有相同类型的项目。


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

解决方案

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.

这篇关于如何在WP8中做一个CompositeCollection?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆