You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

动态生成元素时Dynamic Grid宽度不显示问题排查

问题分析与解决方案

你的问题核心出在布局容器的选择控件拉伸属性的配置上,和上层Grid宽度的获取关系不大,咱们一步步调整就能解决:

1. 替换ItemsPanel的StackPanel为Grid

你当前用的StackPanel Orientation="Horizontal"是关键问题——StackPanel的布局逻辑是只给子元素提供其自身所需的最小空间,哪怕设置了拉伸属性也不会让子元素填充整个可用宽度。因为你的ItemsSource里只有一个Grid,直接把ItemsPanel换成Grid就好:

<Grid Grid.Column="1" Background="#FF7E7738">
    <ItemsControl ItemsSource="{Binding ConnectorItemsGridX}" 
                  HorizontalAlignment="Stretch"> <!-- 让ItemsControl填充上层Grid的宽度 -->
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid /> <!-- 替换StackPanel为Grid,支持子元素拉伸 -->
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <!-- 强制每个Item容器填充ItemsControl的可用宽度 -->
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="HorizontalAlignment" Value="Stretch" />
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Grid>

2. 优化C#动态Grid的设置

虽然Grid默认的HorizontalAlignmentStretch,但咱们明确设置一下确保万无一失,另外不需要手动设置Width=Double.NaN(这和默认的Auto效果一致,且当父容器允许拉伸时,Stretch优先级更高):

public ObservableCollection<Grid> ConnectorItemsGridX { get; set; } 

public void DrawConnectors() 
{ 
    Grid mainGrid = new Grid();
    // 明确设置水平对齐为Stretch,让Grid填充父容器宽度
    mainGrid.HorizontalAlignment = HorizontalAlignment.Stretch;

    // 列定义部分保持不变
    ColumnDefinition cd1 = new ColumnDefinition();
    cd1.Width = new GridLength(1, GridUnitType.Star);
    ColumnDefinition cd2 = new ColumnDefinition();
    cd2.Width = new GridLength(1, GridUnitType.Star);
    ColumnDefinition cd3 = new ColumnDefinition();
    cd3.Width = new GridLength(0.6, GridUnitType.Star);
    ColumnDefinition cd4 = new ColumnDefinition();
    cd4.Width = new GridLength(1, GridUnitType.Star);
    
    mainGrid.ColumnDefinitions.Add(cd1);
    mainGrid.ColumnDefinitions.Add(cd2);
    mainGrid.ColumnDefinitions.Add(cd3);
    mainGrid.ColumnDefinitions.Add(cd4);

    // 子Grid部分保持不变(颜色可自行调整回需求值)
    Grid tb1 = new Grid();
    tb1.Background = Brushes.Beige;
    Grid tb2 = new Grid();
    tb2.Background = Brushes.DarkSeaGreen;
    Grid tb3 = new Grid();
    tb3.Background = Brushes.MistyRose;
    Grid tb4 = new Grid();
    tb4.Background = Brushes.Violet;
    
    mainGrid.Children.Add(tb1);
    mainGrid.Children.Add(tb2);
    mainGrid.Children.Add(tb3);
    mainGrid.Children.Add(tb4);
    
    Grid.SetColumn(tb1, 0);
    Grid.SetColumn(tb2, 1);
    Grid.SetColumn(tb3, 2);
    Grid.SetColumn(tb4, 3);

    ConnectorItemsGridX = new ObservableCollection<Grid>();
    ConnectorItemsGridX.Add(mainGrid); 
}

为什么之前固定宽度能显示?

当你给mainGrid设置固定宽度时,StackPanel会按这个固定值分配空间,四个子列就能按比例显示。但没有固定宽度时,StackPanel会让mainGrid收缩到最小(空Grid的最小尺寸为0),所以你看不到任何内容。

修改后,ItemsControl会填充上层Grid的宽度,ItemsPanel用Grid支持子元素拉伸,动态创建的mainGrid也会填充可用宽度,四个子列就会按你设置的Star比例分配宽度,实现和XAML版本完全一致的自适应效果。

内容的提问来源于stack exchange,提问作者programmerJavaPL

火山引擎 最新活动