自定义卡列表框,如谷歌现在

时间:2014-11-04 18:18:34

标签: windows-phone custom-controls

我正在寻找一种方法来为Windows Phone 7.1做一个自定义列表框,就像google now cards一样。效果很简单:两列。下一张卡将尽可能顶。

如果第1列为100px高,第2列为170像素,则下一张卡将在第1列。

enter image description here

我尝试了WrapPanel,但它对齐了每一行的顶部。所以选项是构建一个自定义列表框(或者已经完成一个)。可怜的是,我无法做出一个无限的'查看并添加视图,但我想这不会非常有效。

谢谢!

3 个答案:

答案 0 :(得分:3)

我将在代码更改后添加另一个答案:

public class ViewModel : INotifyPropertyChanged
{
    private Random rnd = new Random(DateTime.Now.Millisecond);

    public ViewModel()
    {
        Items = new List<DataItem>()
                    {
                        new DataItem()
                            {
                                Title = "Title 1",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Green),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 2",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Blue),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 3",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Purple),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 4",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Brown),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 5",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Gray),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 6",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Green),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 7",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Brown),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 8",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Magenta),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 9",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Orange),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 10",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Purple),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 11",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Brown),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                        new DataItem()
                            {
                                Title = "Title 12",
                                Height = rnd.Next(100, 250),
                                Color = new SolidColorBrush(Colors.Red),
                                Content =
                                    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."
                            },
                    };
    }

    public List<DataItem> Items
    {
        set
        {
            int List1Height = 0;
            int List2Height = 1; // set to 1 so first item will end up in List1
            Items1 = new List<DataItem>();
            Items2 = new List<DataItem>();
            foreach (DataItem dataItem in value)
            {
                if (List1Height < List2Height)
                {
                    Items1.Add(dataItem);
                    List1Height += dataItem.Height;
                }
                else
                {
                    Items2.Add(dataItem);
                    List2Height += dataItem.Height;
                }
            }
        }
    }

    private List<DataItem> _items1;

    public List<DataItem> Items1
    {
        get { return _items1; }
        set
        {
            _items1 = value;
            OnPropertyChanged("Items1");
        }
    }

    private List<DataItem> _items2;

    public List<DataItem> Items2
    {
        get { return _items2; }
        set
        {
            _items2 = value;
            OnPropertyChanged("Items2");
        }
    }



    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class DataItem
{
    public string Title { get; set; }
    public int Height { get; set; }
    public SolidColorBrush Color { get; set; }
    public string Content { get; set; }
}

最重要的变化是添加一个名为“Items”的属性。设置此属性后,项目将添加到两个列表中的一个列表中,具体取决于添加项目时哪个项目更短。没有吸气剂,因为我们没有约束这个属性。

我还添加了一些颜色和随机高度用于测试目的,清理了一些XAML以使内容更清晰,并添加了INotifyPropertyChanged支持,因此当Items属性设置并将项目添加到2个列表时,用户界面会自动更新。

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ScrollViewer Margin="10">
        <StackPanel Orientation="Horizontal" >
            <StackPanel Orientation="Vertical" Width="210">
                <ItemsControl ItemsSource="{Binding Items1}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid Height="{Binding Height}" Margin="5" Background="{Binding Color}" >
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="50"/>
                                    <RowDefinition Height="1*"/>
                                </Grid.RowDefinitions>
                                <TextBlock Text="{Binding Title}" Grid.Row="0" Style="{StaticResource PhoneTextLargeStyle}"/>
                                <TextBlock Text="{Binding Content}" Grid.Row="1" TextWrapping="Wrap" Margin="5"/>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl >
            </StackPanel>
            <StackPanel Orientation="Vertical" Width="210">
                <ItemsControl ItemsSource="{Binding Items2}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid  Height="{Binding Height}" Margin="5" Background="{Binding Color}" >
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="50"/>
                                    <RowDefinition Height="1*"/>
                                </Grid.RowDefinitions>
                                <TextBlock Text="{Binding Title}" Grid.Row="0" Style="{StaticResource PhoneTextLargeStyle}"/>
                                <TextBlock Text="{Binding Content}" Grid.Row="1" TextWrapping="Wrap" Margin="5"/>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </StackPanel>
    </ScrollViewer>
</Grid>

注意事项3-6以及4和5如何在同一列中堆叠在一起。 Notice items 3-6 and how 4 and 5 are stacked together in the same column.

我意识到我的答案无法满足您对单个自动方式将项目流入2列之一的需求。但是,它似乎满足了所需的结果:2列滚动列表,其中项目流入最短列。

如果您真的需要它作为控件,那么下一步就是将它变成UserControl或CustomControl。哪一项取决于您的技能和您愿意投入的工作量。

可以在此处找到2的良好比较:http://www.geekchamp.com/articles/user-control-vs-custom-control-in-silverlight-for-wp7

答案 1 :(得分:2)

以下是使用数据绑定到viewmodel的示例。它使用ItemsPanel来堆叠水平StackPanel中的项目:

代码背后:

using System.Collections.Generic;
using Microsoft.Phone.Controls;

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

        }

        public ViewModel ViewModel { get; set; }
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            ViewModel = new ViewModel();
            DataContext = ViewModel;
        }


    }
    public class ViewModel
    {
        public ViewModel()
        {
            Items1 = new List<DataItem>()
                         {
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                         };

            Items2 = new List<DataItem>()
                         {
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                             new DataItem(){Title = "Title", Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque non bibendum nisi. Aenean eu elementum massa. Praesent vel urna id neque tristique maximus."},
                         };
        }
        public List<DataItem> Items1 { get; set; }
        public List<DataItem> Items2 { get; set; }
    }
    public class DataItem
    {
        public string Title { get; set; }
        public string Content { get; set; }
    }
}

和实际的XAML:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

        <ScrollViewer Margin="10">
            <StackPanel Orientation="Horizontal" >
                <StackPanel Orientation="Vertical" Width="210">
                    <ItemsControl ItemsSource="{Binding Items1}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Grid Height="333" Margin="5" Background="Red" >
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="50"/>
                                        <RowDefinition Height="1*"/>
                                    </Grid.RowDefinitions>
                                    <TextBlock Text="{Binding Title}" Grid.Row="0"/>
                                    <TextBlock Text="{Binding Content}" Grid.Row="1" TextWrapping="Wrap"/>
                                </Grid>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl >
                </StackPanel>
                <StackPanel Orientation="Vertical" Width="210">
                    <ItemsControl ItemsSource="{Binding Items2}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Grid Height="200" Margin="5" Background="Blue" >
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="50"/>
                                        <RowDefinition Height="1*"/>
                                    </Grid.RowDefinitions>
                                    <TextBlock Text="{Binding Title}" Grid.Row="0"/>
                                    <TextBlock Text="{Binding Content}" Grid.Row="1" TextWrapping="Wrap"/>
                                </Grid>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </StackPanel>
            </StackPanel>
        </ScrollViewer>
    </Grid>

Resulting scrolling 2-column list

答案 2 :(得分:0)

你应该在里面使用带有一些StackPanels的ScrollViewer:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ScrollViewer Margin="10">
        <StackPanel Orientation="Horizontal">
            <StackPanel Orientation="Vertical" Width="210">
                <Grid Height="200" Margin="5" Background="Blue" />
                <Grid Height="200" Margin="5" Background="Blue"  />
                <Grid Height="200" Margin="5" Background="Blue" />
                <Grid Height="200" Margin="5" Background="Blue" />
                <Grid Height="200" Margin="5" Background="Blue" />
            </StackPanel>
            <StackPanel Orientation="Vertical" Width="210">
                <Grid Height="300" Margin="5" Background="Blue" />
                <Grid Height="300" Margin="5" Background="Blue" />
                <Grid Height="300" Margin="5" Background="Blue"  />
                <Grid Height="300" Margin="5" Background="Blue" />
             </StackPanel>
        </StackPanel>
    </ScrollViewer>
</Grid>

您可能会在内部堆栈面板中放置一些内容(而不是我用作示例的网格)以允许您将数据项绑定到模板,但列出的ScrollViewer / StackPanel解决方案将使您从正确的方向开始