我编写了一个WPF用户控件,其中一部分涉及动态地向画布添加元素,这会影响所述画布的高度。画布嵌套在网格中。当我动态添加我的元素时,画布的高度会发生变化,但画布最终会延伸到整个控件的边缘之外,而不是使控件调整大小并使其自身更高。 如何强制控件正确调整大小? 我得到了我需要调用或覆盖Measure或Arrange的感觉,但我对这两种方法都没有运气 - 可能是因为我用不正确的参数调用它们,或者可能因为它们不是正确的调用方法。 / p>
答案 0 :(得分:16)
您的问题是Canvas面板不会调整大小以适应其内容。
您指的是测量和排列。你熟悉WPF的两遍布局系统吗?阅读本文以获取更多信息:WPF's Layout System。
本文还介绍了不同面板的布局。每种类型的面板都不同。
在WPF中,元素首先有机会确定它们的大小。小组可以根据孩子的大小确定他们的大小,或者他们可以询问固定的大小,无论他们的孩子的大小。 Canvas就是后者的一个例子。
接下来会告诉他们他们的身材,并要求他们安排自己和孩子。
“网格”面板类型不仅允许行和列,还非常擅长自动调整内容大小。
StackPanel类型在其定向的维度中根本不会自动调整大小,但它会在另一个维度中自动调整大小。
Canvas可以自动调整大小以填充空间,但它永远不会让它的子节点自动调整大小。它在指定的坐标处绘制孩子,并不关心它们有多大。
我建议尝试只有一行/列的网格。
或者您可以创建一个具有更好自动调整功能的新Canvas类。在测量期间,您需要相应地测量子元素和Canvas的大小。你可能会发现这样的课程很有帮助。
以下是WPF中Auto Layout的文章。
如果你想创建一个自定义面板,这里有一个子主题:Custom Panel Elements。
编辑: 还有一件事:您还可以将子元素的宽度/高度绑定到画布上的ActualWidth和ActualHeight属性,以便子级调整其父级的大小。如有必要,您可以使用转换器设置大小比率。
答案 1 :(得分:2)
您是否尝试将所有内容(您的自定义控件内容)包装到Viewbox中? 例如
<UserControl>
<Border BorderBrush="Black" BorderThickness="1">
<Viewbox>
<Grid>
<TextBlock Name="txtDefault" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16" Foreground="Black" Opacity="0.5" Text="Default" />
<TextBlock Name="txtValue" FontSize="16" Foreground="Black" Visibility="Collapsed" />
<TextBlock Name="txtKey" Grid.Column="1" FontSize="18" Foreground="Black" Visibility="Collapsed" />
</Grid>
</Viewbox>
</Border>
</UserControl>
答案 2 :(得分:1)
您需要覆盖控件的MeasureOverride方法,并从那里返回所需的大小(画布的大小)。然后父控件会自行调整大小以适应它的孩子(如果可以的话)。
答案 3 :(得分:0)
您可以使用UniFormGrid对此进行存档。设置列或行等于1,以便您可以获得垂直/水平排列的项目
<UniformGrid Columns="1">
<Button Content="Content 1"/>
<Button Content="Content 2"/>
<Button Content="Content 3"/>
</UniformGrid>