WPF使用网格作为项目主机自动在单个``单元格''中堆叠多个项目 [英] wpf using grid as itemshost stacking multiple items in single 'cell' automatically

查看:88
本文介绍了WPF使用网格作为项目主机自动在单个``单元格''中堆叠多个项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将一个项目控件绑定到一个数据源,并使用一个网格作为我的项目主机.我希望这些项目将自己定位到网格中的正确单元格中(我可以这样做),并且还要自己堆叠,以使它们不会彼此重叠(我不知道如何将这些项目插入到网格中).面板或网格中的其他面板).

I am binding an items control to a datasource and using a grid as my itemshost. I wish to have the items locate themselves into the correct cell in the grid (I can do this), and also stack themselves so they are not all on top of each other (I can't figure out how to insert the items into a stackpanel or other panel in the grid).

这是两个类的.cs文件:

here is the .cs file for the two classes:

   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将项目插入动态创建的堆栈面板

My problem is that all the buttons ending with 'a' are under the buttons ending in b. I can't see how to use XAML to insert the items into a dynamically created stackpanel

我试图创建一个派生自Grid的类,以为自己拦截子项的添加以自己添加堆栈面板,然后将这些子项从网格移动到堆栈面板,但是尝试在itemshost中操纵这些子项会导致异常被扔.

I tried to create a class derived from Grid, thinking to intercept the addition of the children to add stackpanels myself and then move the children from the grid to the stackpanels, but attempting to manipulate the children in an itemshost causes an exception to be thrown.

最终,我只希望数据源中的项目能够绑定到网格中的单元格",并且如果多个项目绑定到同一单元格,我希望它们进行堆叠.

Ultimately I just want the items in my datasource to be able to bind to a 'cell' in the grid, and if multiple items bind to the same cell, I want them to stack.

推荐答案

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

Here is the solution using the hints from nmclean (Thanks so much) This section establishes the grouping which will be used to distribute the elements around the grid.

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


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


        </CollectionViewSource.GroupDescriptions>

    </CollectionViewSource>

本节是绑定到collectionviewsource中数据的主列表框.containerstyle包含将groupitem放入网格中正确单元格中的绑定.网格位于groupstyle.panel

this section is the main listbox bound to the data in the collectionviewsource, The containerstyle contains the bindings to put the groupitem into the correct cells in the grid. The grid is in the 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>

这是您需要时的整体解决方案:

Here is the total solution in case you need it:

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

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

The code file looks like this now:

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

}

这篇关于WPF使用网格作为项目主机自动在单个``单元格''中堆叠多个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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