如何将网格设置为 Items 控件的模板? [英] How to setup a grid as template for an Items control?

查看:16
本文介绍了如何将网格设置为 Items 控件的模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个 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 GridItemTemplate,并使用 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 控件的模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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