wpf - 如何将网格设置为 Items 控件的模板?

标签 wpf grid itemscontrol itemssource

我正在尝试创建 ItemsControl使用网格作为其ItemsPanel以这样一种方式,它有两列,其中第一列的宽度是该列中最宽的项目的宽度,并且有尽可能多的行来显示所有项目

基本上,我想要以下,但不知何故在 ItemsControl这样我就可以绑定(bind)到对象集合:

<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 的回答效果很好,这是一个工作示例。

(我将 Grid.IsSharedSizeScope="True"移到了 ItemsPanel,不确定 Rachel 是否打算将其放入 ItemTemplate 中(这不起作用))
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 这里有多个问题:

  • 让您的第一列与最大项目的宽度匹配
  • 生成动态行数
  • ItemsControl 的每次迭代生成多个项目

  • 最后一个确实是最大的问题,因为 ItemsControl包裹每个 ItemTemplateContentPresenter ,因此没有默认方法可以为 ItemsControl 的每个迭代在面板中创建多个项目。 .您的最终结果将如下所示:
    <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> 
    
    我最好的建议是创建一个 ItemTemplate包含一个 1x2 Grid , 并使用 Grid.IsSharedSizeScope使第一列的宽度共享。 (ItemsPanelTemplate 将保持默认 StackPanel 。)
    这样,最终结果将如下所示:
    <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> 
    

    关于wpf - 如何将网格设置为 Items 控件的模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16596579/

    相关文章:

    WPF itemscontrol 子对齐

    c# - TemplateBinding 未传递到 ControlTemplate.Resources 中创建的 VisualBrush

    WPF 渲染性能缓慢

    python - 在 tkinter 窗口上使用网格管理器时如何实现滚动条

    selenium - 无法使用 Selenium Grid 访问虚拟机上的节点

    c# - ItemsControl 中 WPF 中的可拖动对象?

    WPF ItemsControl : restrict the type of the item to a specific one

    wpf - 使用 WPF 时如何消除菜单字体模糊?

    wpf - 如何在 MFC 应用程序中托管 WPF 内容?

    html - Bootstrap网格不会初始化,但是其他所有功能都可以