如何让ItemsControl填满所有可用空间?

7
我有一个ItemsControl,它的ItemsSource绑定到一个项目列表。每个项目的大小尽可能小,我需要控件和其中的项目拉伸以适应所有可用空间。
我尝试在控件和其项目上(使用样式)将VerticalAlignment设置为Stretch。我还尝试将ItemsControl包装在DockPanel中,并将ItemsControl停靠到底部。如何使ItemsControl动态调整大小?
此外,一些项目的可见性设置为Collapsed(通过相同的样式)。这会影响到这个问题吗?
<DockPanel HorizontalAlignment="Stretch">
    <ItemsControl DockPanel.Dock="Bottom"
                    ItemsSource="{Binding Owner.LoadPointCharts}"
                    HorizontalAlignment="Stretch"
                    x:Name="ItemsControl">
        <ItemsControl.ItemContainerStyle><!--Height="{Binding Path=Height, RelativeSource={RelativeSource AncestorType={x:Type DockPanel}}}"-->
            <Style TargetType="ContentPresenter">
            <Setter Property="VerticalAlignment"
                    Value="Stretch" />

                <Setter Property="Visibility">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource CompareIndexToVisibilityConverter}">
                        <Binding Path="Index" />
                        <Binding Path="SelectedIndex" />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            </Style >
        </ItemsControl.ItemContainerStyle>
        </ItemsControl>
</DockPanel> 

不确定您的意思。我的ItemsControl中的项默认情况下是垂直拉伸的。您的ItemTemplate是什么样子的? - Clemens
ItemTemplate 没有变化。ContentPresenter 绑定到一个具有 DataTemplate 的对象,该模板使用 DataTemplate(根据 MVVM)。DataTemplate 是 WPF 工具包图表控件的模板。我也将 VerticalAlignment 设置为 Stretch。 - kleineg
试试看将那个 DataTemplate 替换为仅包含 TextBlock 的模板,然后设置 TextBlock 的背景。 - Clemens
@Clemens 这是(我在下面的答案评论中已经这么说了,不幸的是它并没有起作用) - kleineg
@Clemens 不,我没有,我应该设置什么? - kleineg
显示剩余2条评论
4个回答

20

在我看来,被接受的答案有些过于复杂了。 此外,在网格中设置项目的位置可能很麻烦。 您需要使用UniformGrid。

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

5

我也遇到了同样的问题,后来发现 ItemsControl 默认使用 StackPanel 来布局其子元素。将其替换为 Grid 就解决了问题:

 <ItemsControl>
      <ItemsControl.ItemsPanel>
           <ItemsPanelTemplate>
                <Grid />
           </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
 </ItemsControl>

编辑:此方法仅适用于一个子元素!


3
以网格为模板不起作用,因为项目被放置在相同的位置并重叠在一起! - Jinjinov
1
你说得对,我只用了一个子元素。我已经编辑了我的回答。 - SpeziFish

1

使用网格作为模板不起作用,因为项目被放在上下位置。使用DockPanel可以正常工作:

  <ItemsControl>
  <ItemsControl.ItemsPanel>
       <ItemsPanelTemplate>
            <DockPanel/>
       </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>


1
使用 DockPanel 会导致只有最后一个项目拉伸并填充可用空间,因此项目不会均匀分布。 - Jinjinov

1

我认为这应该可以工作,具体取决于最外层的Grid包含了什么内容。

默认情况下,一个Grid会拉伸以填充其容器,并导致其内容被拉伸以填充自身。如果您将ItemsControl放在DockPanel中并在ItemsControl上设置了 DockPanel.Dock="Bottom",它将填充DockPanel底部。因此,如果我理解正确,那不是你想要的。

<Grid>
    <ItemsControl 
        ItemsSource="{Binding Owner.LoadPointCharts}"
        x:Name="ItemsControl"
        >
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="VerticalAlignment" Value="Stretch" />
                <Setter Property="HorizontalAlignment" Value="Stretch" />

                <Setter Property="Visibility">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource CompareIndexToVisibilityConverter}">
                            <Binding Path="Index" />
                            <Binding Path="SelectedIndex" />
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style >
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Grid>

Grid 是 XAML 布局中一种类似于瑞士军刀的落锚方式。可以随处使用。

如果您想要在 DockPanel 中停靠其他内容,这里是一个简单的 DockPanel 布局:

<Window xmnls:blah="blah blah etc.">
    <Window.DataContext>
        <local:MyViewModel />
    </Window.DataContext>
    <Grid>
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <!-- Menu Items-->
            </Menu>
            <Grid>
                <!-- 
                This assumes we've got a DataTemplate in a resource dictionary  
                somewhere with DataType="{x:Type local:MyViewModel}" 
                -->
                <ContentControl
                    Content="{Binding}"
                    />
            </Grid>
        </DockPanel>
    </Grid>
</Window>

我尝试将ItemsControl放入网格中,但没有成功。 - kleineg
然后它们被堆叠在彼此之上。我试图让它们在垂直方向上拉伸。至少,如果有一个项目的列表,它应该占据整个空间。 - kleineg
我已经找到了适合我的监视器的最佳尺寸,如果我时间不够了,我可以将高度设置为固定大小(我尝试过,它能很好地呈现)。除非有人尝试在不同的监视器上运行它。 - kleineg
1
其实,我刚刚弄明白了,我使用了一个setter来将该项的高度设置为其所有者的ActualHeight,很容易放入一个转换器来除以n。再次感谢你。 - kleineg
1
@kleineg 如果它无法滚动,UniformGrid可能是作为ItemsPanel的完美选择。我刚刚发现了这个。 - 15ee8f99-57ff-4f92-890c-b56153
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接