问题描述
我正在尝试创建一个 ItemsControl
,它使用网格作为其 ItemsPanel
,使其具有两列,其中第一列的宽度是宽度该列中最宽的项目,并且具有显示所有项目所需的行数
I'm trying to create an ItemsControl
that uses a grid as its ItemsPanel
in such a way that it has two columns, where the first columns width is the width of the widest item in that column, and has as may rows needed to display all the items
基本上,我想要以下内容,但以某种方式在 ItemsControl
中,以便我可以绑定到对象集合:
Basically, I want the following, but somehow within an ItemsControl
so that I can bind to a collection of objects:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Content="{Binding Items[0].Header}"/>
<TextBox Text="{Binding Items[0].Content}" Grid.Column="1"/>
<Label Content="{Binding Items[1].Header}" Grid.Row="1"/>
<TextBox Text="{Binding Items[1].Content}" Grid.Row="1" Grid.Column="1"/>
<Label Content="{Binding Items[2].Header}" Grid.Row="2"/>
<TextBox Text="{Binding Items[2].Content}" Grid.Row="2" Grid.Column="1"/>
</Grid>
Rachels 的回答效果很好,这是一个工作示例.
Edit : Rachels answer worked great, here is a working example.
(我将 Grid.IsSharedSizeScope="True" 移到了 ItemsPanel,不确定 Rachel 是否打算将其放入 ItemTemplate(这不起作用))
(I moved the Grid.IsSharedSizeScope="True" to the ItemsPanel, not sure if Rachel meant to put it in the ItemTemplate (which didn't work))
namespace WpfApplication23
{
public partial class Window1 : Window
{
public List<Item> Items { get; set; }
public Window1()
{
Items = new List<Item>()
{
new Item(){ Header="Item0", Content="someVal" },
new Item(){ Header="Item1", Content="someVal" },
new Item(){ Header="Item267676", Content="someVal" },
new Item(){ Header="a", Content="someVal" },
new Item(){ Header="bbbbbbbbbbbbbbbbbbbbbbbbbb", Content="someVal" },
new Item(){ Header="ccccccc", Content="someVal" }
};
InitializeComponent();
DataContext = this;
}
}
public class Item
{
public string Header { get; set; }
public string Content { get; set; }
}
}
<Window x:Class="WpfApplication23.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Grid.IsSharedSizeScope="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Header}"/>
<TextBox Text="{Binding Content}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
推荐答案
这里对于一个 ItemsControl
有多个问题:
There are multiple problems here for an ItemsControl
:
- 让您的第一列与最大项目的宽度相匹配
- 生成动态行数
- 为
ItemsControl
的每次迭代生成多个项目
- Getting your first column to match the width of the largest item
- Generating a dynamic number of rows
- Generating more than one item for each iteration of the
ItemsControl
最后一个确实是最大的问题,因为一个ItemsControl
将每个ItemTemplate
包装在一个ContentPresenter
中,所以没有默认的方式为 ItemsControl
的每个迭代在面板中创建多个项目.您的最终结果将如下所示:
The last one is really the biggest problem, because an ItemsControl
wraps each ItemTemplate
in a ContentPresenter
, so there is no default way of creating more than one item in the panel for each Iteration of the ItemsControl
. Your end result would look like this:
<Grid>
...
<ContentPresenter>
<Label Content="{Binding Items[0].Header}"/>
<TextBox Text="{Binding Items[0].Content}" Grid.Column="1"/>
</ContentPresenter>
<ContentPresenter>
<Label Content="{Binding Items[1].Header}" Grid.Row="1"/>
<TextBox Text="{Binding Items[1].Content}" Grid.Row="1" Grid.Column="1"/>
</ContentPresenter>
<ContentPresenter>
<Label Content="{Binding Items[2].Header}" Grid.Row="2"/>
<TextBox Text="{Binding Items[2].Content}" Grid.Row="2" Grid.Column="1"/>
</ContentPresenter>
</Grid>
我最好的建议是创建一个包含 1x2 Grid
的 ItemTemplate
,并使用 Grid.IsSharedSizeScope
来制作第一列共享.(ItemsPanelTemplate
将保持默认的 StackPanel
.)
My best suggestion would be to create an ItemTemplate
that contains a 1x2 Grid
, and use Grid.IsSharedSizeScope
to make the width of the first column shared. (The ItemsPanelTemplate
would remain the default StackPanel
.)
这样,最终结果将如下所示:
This way, the end result would look like this:
<StackPanel>
<ContentPresenter>
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Header}"/>
<TextBox Text="{Binding Content}" Grid.Column="1"/>
</Grid>
</ContentPresenter>
<ContentPresenter>
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Header}"/>
<TextBox Text="{Binding Content}" Grid.Column="1"/>
</Grid>
</ContentPresenter>
...
</StackPanel>
这篇关于如何将网格设置为 Items 控件的模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!