You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现ItemsControl结合UniformGrid填充可用空间并让自定义MyControl自适应容器

解决WPF ItemsControl自定义控件自适应布局问题

看起来你遇到的核心问题是自定义的MyControl没有正确响应父容器的尺寸约束,加上嵌套的Viewbox和固定尺寸设置,导致控件无法自动填充可用空间。我帮你梳理了几个关键修改点,一步步解决这个问题:


第一步:修正外层ItemsControl的布局

首先,你外层的Viewbox其实是多余的,甚至会破坏UniformGrid的自适应逻辑——UniformGrid本身就会把父容器的空间平均分配给4行3列的项,外层Viewbox的缩放会强制拉伸内容,反而让子控件无法正确获取父容器的尺寸。

修改后的外层代码:

<Grid.Row="1">
    <ItemsControl Background="Yellow" Name="icCalendarios" ItemsSource="{Binding Calendarios}" Margin="0,0,30,0">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="4" Columns="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <myControls:MyControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid.Row="1">

关键修改:

  • 移除了外层的Viewbox
  • 删掉了ItemsControl的HorizontalAlignment="Center"(显式设置Center会阻止控件填充可用空间,默认的Stretch才是我们需要的)

第二步:修复MyControl的内部自适应

你的MyControl里有几个阻碍自适应的点:固定尺寸的Border、绑定死的Viewbox宽度,还有没有正确配置的容器布局。

修改后的MyControl代码:

<DockPanel LastChildFill="True">
    <Viewbox Name="vbReescalado" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="UniformToFill">
        <DockPanel LastChildFill="True">
            <!-- 日期和标题区域 -->
            <Grid DockPanel.Dock="Top" Height="Auto">
                <TextBlock Text="{Binding Date}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <TextBox Foreground="Black" Name="txtEncabezado" FontSize="12" BorderBrush="Transparent" 
                         BorderThickness="0" Background="Transparent" VerticalAlignment="Center" 
                         TextAlignment="Center" HorizontalAlignment="Stretch" Padding="5" 
                         Text="{Binding Encabezado}"/>
            </Grid>

            <!-- 星期名称区域 -->
            <ItemsControl ItemsSource="{Binding NombresDias}" DockPanel.Dock="Top">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock TextAlignment="Center" Text="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="1" Columns="8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>

            <!-- 日历网格区域 -->
            <ItemsControl ItemsSource="{Binding Dias}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border BorderThickness="0.25" BorderBrush="{Binding Converter={StaticResource ColorRecuadroDiaConverter}}" 
                                HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                            <Border Name="InnerBorder" Background="{Binding ColorDia}" 
                                    BorderBrush="{Binding Path=ColorRecuadroExterno}" 
                                    BorderThickness="{Binding Path=GrosorRecuadroExterno}"
                                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                                <DockPanel LastChildFill="True">
                                    <!-- 日期数字 -->
                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" FlowDirection="RightToLeft" 
                                                HorizontalAlignment="Stretch">
                                        <TextBox TextAlignment="Right" BorderBrush="Transparent" Background="Transparent" 
                                                 Text="{Binding Path=., Converter={StaticResource DateConverter}}"
                                                 VerticalAlignment="Top">
                                            <TextBox.Style>
                                                <Style TargetType="{x:Type TextBox}">
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding IsTargetMonth}" Value="false">
                                                            <Setter Property="Foreground" Value="Gray"></Setter>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </TextBox.Style>
                                        </TextBox>
                                    </StackPanel>
                                    <!-- 备注文本框 -->
                                    <TextBox IsEnabled="{Binding IsEnabled}" AcceptsReturn="True" TextWrapping="Wrap" 
                                             BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Disabled" 
                                             Background="{x:Null}" Foreground="{Binding Path=ColorTexto}" 
                                             Text="{Binding Path=Notes}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
                                </DockPanel>
                            </Border>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="6" Columns="8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DockPanel>
    </Viewbox>
</DockPanel>

关键修改点:

  1. 移除固定尺寸:删掉了Border的Width="25"和Height="25",改用HorizontalAlignment="Stretch"和VerticalAlignment="Stretch"让每个日期单元格填充UniformGrid的单元格空间。
  2. 去掉Viewbox的宽度绑定:移除了Width="{Binding ElementName=MesConEventos, Path=WidthReescalado}",让Viewbox完全填充父容器的空间,同时保留Stretch="UniformToFill"确保内部内容按比例缩放。
  3. 显式设置DockPanel的LastChildFill:给所有DockPanel加上LastChildFill="True",让最后一个子控件(日历网格)填充剩余的所有空间。
  4. 调整文本控件的对齐:让所有TextBlock和TextBox使用Stretch对齐,确保它们在各自的容器内正确填充。

调试小技巧

如果还是有部分区域没有正确填充,可以给各个容器临时加上背景色(比如给UniformGrid加Background="LightBlue",给MyControl加Background="LightGreen"),这样能直观看到每个控件的布局范围,快速定位问题所在。

另外,如果你觉得窗口缩放时字体大小不合适,内部的Viewbox会自动帮你缩放文本内容,确保在任何尺寸下都清晰可见。

内容的提问来源于stack exchange,提问作者Álvaro García

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:52:28