wpf使用grid作为itemshost自动堆叠单个'cell'中的多个项目

时间:2013-07-25 16:07:26

标签: wpf grid itemscontrol

我将一个项控件绑定到一个数据源,并使用一个网格作为我的itemshost。我希望将这些项目放置在网格中的正确单元格中(我可以这样做),并且还将它们自己堆叠起来,使它们不是彼此重叠(我无法弄清楚如何将项目插入到网格中的stackpanel或其他面板。)

这是两个类的.cs文件:

   public class listofdata
    {
        public List<data> stuff { get; set; }
        public listofdata()
        {
            stuff = new List<data>();
            stuff.Add(new data(0, 0, "zeroa"));
            stuff.Add(new data(0, 0, "zerob"));
            stuff.Add(new data(1, 0, "onea"));
            stuff.Add(new data(1, 0, "oneb"));
            stuff.Add(new data(1, 1, "twoa"));
            stuff.Add(new data(1, 1, "twob"));
        }
    }

    public class data
    {
        public int x { set; get; }
        public int y { set; get; }
        public string text { get; set; }
        public data(int x, int y, string text)
        {
            this.x = x;
            this.y = y;
            this.text = text;
        }
    }
}

这是我的XAML

   <Window x:Class="GridTester.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:src="clr-namespace:GridTester"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"

    Title="MainWindow" >
<Window.Resources>
    <DataTemplate DataType="{x:Type src:data}">
        <Button Content="{Binding text}"/>
    </DataTemplate>
    <src:listofdata x:Key="MyDataSource"> </src:listofdata>


</Window.Resources>
<ListBox Name="Main" ItemsSource="{Binding Source={StaticResource MyDataSource},Path=stuff}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid Name="MyGrid">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>

                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemContainerStyle>
        <Style>
            <Setter Property="Grid.Column" Value="{Binding x}"/>
            <Setter Property="Grid.Row" Value="{Binding y}"/>
        </Style>
    </ListBox.ItemContainerStyle> 

</ListBox>


</Window>

我的问题是所有以'a'结尾的按钮都在以b结尾的按钮下。 我看不到如何使用XAML将项目插入动态创建的堆栈面板

我尝试创建一个派生自Grid的类,想要拦截子项的添加以自己添加stackpanels然后将子项从网格移动到stackpanels,但是尝试操作itemshost中的子项导致异常被抛出。

最终我只希望我的数据源中的项目能够绑定到网格中的“单元格”,如果多个项目绑定到同一个单元格,我希望它们能够堆叠。

2 个答案:

答案 0 :(得分:1)

您可以在HighCore建议的数据级别执行此操作,但由于当前数据结构已包含必要信息,因此ItemsControl应该可以处理它。考虑在ListBox的项集合中添加group description,并使用GroupStyle为StackPanel的Panel

答案 1 :(得分:1)

以下是使用nmclean提示的解决方案(非常感谢) 此部分建立用于在网格周围分布元素的分组。

<CollectionViewSource Source="{Binding Source={StaticResource MyDataSource}}" x:Key="cvs">


        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="ordinal"/>


        </CollectionViewSource.GroupDescriptions>

    </CollectionViewSource>

此部分是绑定到collectionsviewsource中数据的主列表框,containerstyle包含将groupitem放入网格中正确单元格的绑定。网格位于groupstyle.panel

  <ListBox  ItemsSource ="{Binding Source={StaticResource cvs}}"   >
    <ListBox.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Grid.Row" Value="{Binding Items[0].y,diag:PresentationTraceSources.TraceLevel=High}" />
                    <Setter Property="Grid.Column" Value="{Binding Items[0].x,diag:PresentationTraceSources.TraceLevel=High}" />


                </Style>
            </GroupStyle.ContainerStyle>
            <GroupStyle.Panel>
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition></RowDefinition>
                            <RowDefinition></RowDefinition>
                            <RowDefinition></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </GroupStyle.Panel>
        </GroupStyle>
    </ListBox.GroupStyle>

以下是您需要的整体解决方案:

<Window x:Class="GridTester.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
        xmlns:src="clr-namespace:GridTester"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"

        Title="Window1" Height="300" Width="300" Name="TOPWindow">
    <Window.Resources>

        <DataTemplate DataType="{x:Type src:data}">
            <Button Content="{Binding text}"/>
        </DataTemplate>
        <src:listofdata x:Key="MyDataSource"></src:listofdata>
        <CollectionViewSource Source="{Binding Source={StaticResource MyDataSource}}" x:Key="cvs">


            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="ordinal"/>


            </CollectionViewSource.GroupDescriptions>

        </CollectionViewSource>


    </Window.Resources>



    <ListBox  ItemsSource ="{Binding Source={StaticResource cvs}}"   >
        <ListBox.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Grid.Row" Value="{Binding Items[0].y,diag:PresentationTraceSources.TraceLevel=High}" />
                        <Setter Property="Grid.Column" Value="{Binding Items[0].x,diag:PresentationTraceSources.TraceLevel=High}" />


                    </Style>
                </GroupStyle.ContainerStyle>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition></RowDefinition>
                                <RowDefinition></RowDefinition>
                                <RowDefinition></RowDefinition>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition></ColumnDefinition>
                                <ColumnDefinition></ColumnDefinition>
                                <ColumnDefinition></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </ListBox.GroupStyle>


    </ListBox>



</Window>

代码文件现在看起来像这样:

  public class listofdata : List<data>
{

    public listofdata()
    {

        Add(new data(0, 0, "zeroa"));
        Add(new data(0, 0, "zerob"));
        Add(new data(1, 0, "onea"));
        Add(new data(1, 0, "oneb"));
        Add(new data(1, 1, "twoa"));
        Add(new data(1, 1, "twob"));


    }

}

public class data
{
    public int x { set; get; }
    public int y { set; get; }
    public int ordinal { get { return x * 1000 + y; } }
    public string text { get; set; }
    public data(int x, int y, string text)
    {
        this.x = x;
        this.y = y;
        this.text = text;
    }

}