如何在数据绑定列表控件中获取特定布局

时间:2014-10-24 22:22:34

标签: c# layout windows-runtime windows-phone-8.1

我想按照以下顺序在Windows Phone 8.1应用中布置我的项目,而不是Silverlight:

enter image description here

我做了一些研究并尝试了不同的面板,但我找不到合适的面板:[ 我可以使用网格和设计,但我想在绑定上添加项目然后我将不得不以某种方式更改网格:/

xaml布局

<Page.DataContext>
    <uc:Test/>
</Page.DataContext>

<ScrollViewer>
    <ItemsControl ItemsSource="{Binding t}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="Aqua"
                        BorderThickness="3"
                    Width="100" Height="100">
                    <TextBlock Text="{Binding}"/>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ScrollViewer>

test.cs中

public class Test
{
    public ObservableCollection<string> t { get; set; }
    public Test()
    {
        t = new ObservableCollection<string>();
        t.Add("a");
        t.Add("b");
        t.Add("c");
        t.Add("d");
        t.Add("e");
    }
}

修改

另外,我确实在下面的评论中写了错误的信息,抱歉。 每个项目都有相同的宽度,因此计数和宽度将给出我在列和行中的位置。

到目前为止,PrepareContainerForItemOverride的实现:

public class ExtendedItemsControl : ItemsControl
{
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);

        var grid = element as ContentPresenter;
        var count = 0; // <- Count of Items in the Grid
        var width = 0; // <- width of the current Element

        //if (count * width / grid.ActualWidth > 1)
        //    grid.RowDefinitions.Add(new RowDefinition());

        Grid.SetRow(grid, 0);
    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用网格和ItemsControl来实现ItemsSource绑定:

  • 首先,将Grid设置为ItemsControl&#39; s ItemsPanel
  • 其次,继承ItemsControl以在其子项上设置适当的Grid.RowGrid.Column属性

对于第一部分(从图片看起来就像你有4列和3行):

<local:ExtendedItemsControl ItemsSource="{Binding MyItems}">
    <local:ExtendedItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </local:ExtendedItemsControl.ItemsPanel>
</local:ExtendedItemsControl>

对于第二部分,我建议覆盖OnItemsChanged,并根据需要在每个项容器上设置Grid附加属性。您可以使用项的隐式序列来执行此操作:

public class ExtendedItemsControl : ItemsControl
{
    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);

        var item2 = this.ItemContainerGenerator.ContainerFromItem(e.NewItems[1]);
        Grid.SetColumn(item2, 1);

        var item3 = this.ItemContainerGenerator.ContainerFromItem(e.NewItems[2]);
        Grid.SetColumn(item3, 2);
        Grid.SetColumnSpan(item3, 2);

        var item4 = this.ItemContainerGenerator.ContainerFromItem(e.NewItems[3]);
        Grid.SetRow(item4, 1);

        // etc ...
    }
}

以上假设您的源集合在绑定后不会更改 - 如果它确实发生了更改,您可以考虑改为覆盖PrepareContainerForItemOverride,并参考属性设置其Grid Row / Column属性在项目模型上(&#34; ItemIndex&#34;或其他):

protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
    base.PrepareContainerForItemOverride(element, item);
    var contentPresenter = (ContentPresenter)element;
    var itemModel = (MyItemModel)item;
    switch (itemModel.ItemIndex)
    {
        case 1:
            Grid.SetColumn(contentPresenter, 1);
            break;
        case 2:
            Grid.SetColumn(contentPresenter, 2);
            Grid.SetColumnSpan(contentPresenter, 2);
            break;
        // etc
    }
}

答案 1 :(得分:1)

没有标准控件可以为您提供任意数量的不同尺寸项目所需的布局,而无需使用自定义放置代码,但您可以根据需要自定义控件。

Mark Rideout在How To: Create a Variable Sized Grouped GridView (like the store)为Windows Store 8.0创建了一个自定义的GridView示例,并且您将用于Windows Phone Runtime应用的技术基本相同。在他的控制下,他覆盖PrepareContainerForItemOverride函数来查看各个数据项,看它们是小型,中型还是大型,然后在VariableSizedWrapGrid中适当地设置它们的列和跨度。 / p>

如果您想要显示的确切位置(而不是排列内容)并希望限制为7,那么您可以将ItemsPanel设置为Grid而不是VariableSizedWrapGrid,并以相同的方式将项目设置为特定的行和列