TL;DR:通过在 Grid 中有一个 1 像素的空行,您正在剪切 Ellipse。
问题存在于多个层面。你的外部Grid 有一个Width 和Height 集。接下来你的RowDefinition 有一个Height 集,你的Ellipse 的大小比两个高度都大。
<Grid Width="128" Height="120">
<Grid.RowDefinitions>
<RowDefinition Height="120" />
<RowDefinition Height="1" x:Name="ChangeHeightRow" />
</Grid.RowDefinitions>
<Grid>
<Canvas Background="Red">
<Ellipse Width="140" Height="140" Fill="Green" />
</Canvas>
</Grid>
</Grid>
通过设置这些大小,您可以让其他控件更接近内部控件,而不是使用 Auto 作为行的大小,而没有使用 (=auto) 作为 Grid 的大小。
在您的初始代码中,您有一个带有Ellipse 的Grid 行和一个1 像素高的空行。默认情况下,XAML 控件具有 Z 轴,其中在 XAML 文件底部声明的项目是可视层中最顶层的控件。因此,对于您的网格,如果重叠,您的第二行位于第一行的顶部。由于Ellipse 泄漏到行外,因此将第二行绘制在其上并剪裁您的Ellipse。
通过将高度设置为 0,第二行不再绘制,也无法剪辑您的控件。
为了更清楚地说明这一点,我稍微调整了您的 XAML,在您的网格之外添加了另一个 StackPanel 并添加了一个 Button。如您所见,Button 绘制在Ellipse 之上,正如它在下面的 XAML 中定义的那样,因此在 Z 轴上获得了更高的可视层。
<StackPanel Width="130">
<Grid Width="128" Height="120">
<Grid.RowDefinitions>
<RowDefinition Height="120" />
<RowDefinition Height="0" x:Name="ChangeHeightRow" />
</Grid.RowDefinitions>
<Grid>
<Canvas Background="Red">
<Ellipse Width="140" Height="140" Fill="Green" />
</Canvas>
</Grid>
</Grid>
<Button Background="Black" Foreground="White">Test</Button>
</StackPanel>
如果我们将 StackPanel 更改为 Grid,我们将有相同的行为。然而,在 XAML 声明中将 Button 移动到顶部(并将 Grid.Row 保持为 1,使其位于 Ellipse 下方),您会注意到它现在位于 Ellipse 之后,因为 Z 层的顺序不同。
<Grid Width="130">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Background="Black" Foreground="White" Grid.Row="1">Test</Button>
<Grid Width="128" Height="120" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="120" />
<RowDefinition Height="0" x:Name="ChangeHeightRow" />
</Grid.RowDefinitions>
<Grid>
<Canvas Background="Red">
<Ellipse Width="140" Height="140" Fill="Green" />
</Canvas>
</Grid>
</Grid>
</Grid>