我将一个项控件绑定到一个数据源,并使用一个网格作为我的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中的子项导致异常被抛出。
最终我只希望我的数据源中的项目能够绑定到网格中的“单元格”,如果多个项目绑定到同一个单元格,我希望它们能够堆叠。
答案 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;
}
}