首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Silverlight中获得此类型的布局?

如何在Silverlight中获得此类型的布局?
EN

Stack Overflow用户
提问于 2011-03-24 11:07:17
回答 2查看 90关注 0票数 1

我有一个列表框,它绑定到一个简单的对象列表。我们知道,默认情况下,列表框将其项目作为Stackpanel的宿主,因此它以这种方式布局项目

代码语言:javascript
复制
item1
item2
item3
item4
item5
item6

但是,我有一些条件,通过这些条件,我可以检查项目是水平还是垂直显示,因此项目可以以这种方式进行布局

例如:-

代码语言:javascript
复制
item1
item2
item3 item4 item 5
item6

怎么可能做到这一点?

(如果你想知道为什么我需要这样的东西,一个示例场景是"facebook style updates“,如果用户连续上传3-4张照片,它们并不总是出现在下一行,但它可能水平出现,而如果他发布了一些事件,它会出现在下一行。)

提前感谢:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-24 17:29:59

解决方案的基本原理是在ListBoxItemTemplate中使用另一个ItemsControl。此ItemsControlItemsPanel应为水平方向的StackPanel

这是一个基本的例子。让我们从一些非常简单的testdata开始:

代码语言:javascript
复制
public class TestStringList : List<string>
{
    public TestStringList()
    {
        AddRange(new[] {"Anthony", "Kar", "Martin", "Jon", "Erik", "Darin",
            "Balus", "Mike", "Hans", "Alex", "Anomie", "David" });

    }
}

现在,我们希望在ListBox中显示此列表,但将所有首字母相同的姓名保留在同一行中。我将使用IValueConverter的一个实现来处理我们需要的分组。如果你使用的是MVVM,那么你的ViewModel就可以使用它了。

代码语言:javascript
复制
public class Grouper : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((IEnumerable<string>)value).OrderBy(s => s).GroupBy(s => s[0]);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这个转换器的输出基本上是IEnumerable<IEnumerable<string>>,这正是我们想要的。外部ListBox将枚举外部集合,内部ItemsControl将枚举内部字符串集,这将是一组具有相同首字母的名称。

下面是xaml:

代码语言:javascript
复制
<UserControl x:Class="SilverlightApplication1.SimpleGrouping"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SilverlightApplication1"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.Resources>
        <local:TestStringList x:Key="TestData" />
        <local:Grouper x:Key="grouper" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <ListBox ItemsSource="{Binding Converter={StaticResource grouper}, Source={StaticResource TestData}}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal" />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding}" Margin="5" />
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>
票数 1
EN

Stack Overflow用户

发布于 2011-03-24 11:29:21

如果使用MVVM pattern,我会这样做:

  1. 为列表框所在的视图创建ViewModel。此VM包含一组ListItemViewModel实例(请参阅下一点)
  2. 创建一个名为ListItemViewModel的ViewModel (根据您的域,为它指定一个更合适的名称)。此视图模型包含一组ItemViewModel实例(请参阅下一点)。
  3. 创建一个名为ItemViewModel的ViewModel。其中的每一项都支持列表中的一项。根据您的域为其指定一个更合适的名称。
  4. 创建一个包含您的列表框的视图。将列表框绑定到VM中的ListItemViewModels集合。此列表框的项模板将是一个ListItemView (请参阅下一点)。items面板模板将是具有ListItemViewModel数据上下文的默认StackPanel.
  5. Create a ListItemView。此视图由ItemViewModel.

支持的水平视图组成(请参见next point).

  • Create an StackPanel ItemViews by the ItemViewModel.

StackPanel ItemViews

您的视图将如下所示,每个视图都有一个相应的ViewModel。

正如我上面所说的,您肯定想要更改视图/视图模型的名称,我的仅用于演示目的:)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5414309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档