将项目列入网格(不是GridView)

时间:2010-11-15 01:40:25

标签: wpf layout

在我的WPF应用程序中,我有一个集合,我想绑定一个控件网格。所需布局的一个示例( TL; DR我想从ItemsSource 获取此内容):

Desired layout http://imagebin.ca/img/27UTke

<Grid ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Grid.Column="0">FileUploader</Label>
    <ComboBox Grid.Row="0" Grid.Column="1" />
    <Button Grid.Row="0" Grid.Column="2">Edit</Button>

    <Label Grid.Row="1" Grid.Column="0">TextUploader</Label>
    <ComboBox Grid.Row="1" Grid.Column="1" />
    <Button Grid.Row="1" Grid.Column="2">Edit</Button>

    <Label Grid.Row="2" Grid.Column="0">UrlShortener</Label>
    <ComboBox Grid.Row="2" Grid.Column="1" />
    <Button Grid.Row="2" Grid.Column="2">Edit</Button>

    <Label Grid.Row="3" Grid.Column="0">ImageUploader</Label>
    <ComboBox Grid.Row="3" Grid.Column="1" />
    <Button Grid.Row="3" Grid.Column="2">Edit</Button>
</Grid>

此示例具有硬编码值;我想动态绑定集合,就像使用ListView一样。但是,使用带有GridView的ListView并不是我想要的;我不需要选择,标题,排序等。对于用户来说,布局是一组整齐的选项,而不是网格中的数据集。


我无法正确地进行此绑定。我尝试在外面使用带有网格的ItemsControl,但忽略了网格:

Failed attempt 1 http://imagebin.ca/img/kTUordk

<Grid ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <ItemsControl ItemsSource="{Binding MyData}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl>
                    <Label Grid.Column="0">Text here</Label>
                    <ComboBox Grid.Column="1" />
                    <Button Grid.Column="2">Edit</Button>
                </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

我还在面板中使用了带有Grid的ItemsControl,但这会为每个项目创建一个Grid,这很难看:

Failed attempt 2 http://imagebin.ca/img/xHo__-JD

<ItemsControl ItemsSource="{Binding Data}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid ShowGridLines="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <Label Grid.Column="0" Content="{Binding Features}" />
                <ComboBox Grid.Column="1" />
                <Button Grid.Column="2">Edit</Button>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

经过一番研究,我发现了列和行网格定义的SharedSizeGroup属性。我曾尝试过以前的尝试;但是,中间列(宽度为*)似乎没有调整自身大小以填充窗口的整个宽度:

Failed attempt 3 http://imagebin.ca/img/nEoMJmy

<ItemsControl ItemsSource="{Binding Data}" Grid.IsSharedSizeScope="True">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid ShowGridLines="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" SharedSizeGroup="A" />
                                <ColumnDefinition Width="*" SharedSizeGroup="B" />
                                <ColumnDefinition Width="Auto" SharedSizeGroup="C" />
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <Label Grid.Column="0" Content="{Binding Features}" />
                <ComboBox Grid.Column="1" />
                <Button Grid.Column="2">Edit</Button>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

完成first layout的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

John Bowen写了一篇关于pitfall of using * with SharedSizeGroups的博客文章。使用他建议的解决方法,我能够获得所需的布局:

<Grid Name="grid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" SharedSizeGroup="A" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" SharedSizeGroup="C" />
    </Grid.ColumnDefinitions>
</Grid>

<ItemsControl ItemsSource="{Binding Data}" Grid.IsSharedSizeScope="True">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid ShowGridLines="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" SharedSizeGroup="A" />
                                <ColumnDefinition Width="{Binding ColumnDefinitions[1].Width, ElementName=grid}" />
                                <ColumnDefinition Width="Auto" SharedSizeGroup="C" />
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <Label Grid.Column="0" Content="{Binding Features}" />
                <ComboBox Grid.Column="1" />
                <Button Grid.Column="2">Edit</Button>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
可悲的是,这似乎是一个黑客;我确信有更好的解决方案可以实现我想要的目标。