C# WPF:调整画布大小以包含其子级
我的任务是画多个矩形并操纵它们。因此,我使用了一个C# WPF:调整画布大小以包含其子级,c#,wpf,canvas,itemscontrol,C#,Wpf,Canvas,Itemscontrol,我的任务是画多个矩形并操纵它们。因此,我使用了一个ItemsControl,它的ItemsPanel作为画布,以及一个包装滚动查看器: <ScrollViewer Height="200" Grid.Row="1" > <ItemsControl Name="rectanglesList" Background="AliceBlue"> <ItemsControl.ItemsPanel> <ItemsPan
ItemsControl
,它的ItemsPanel
作为画布
,以及一个包装滚动查看器
:
<ScrollViewer Height="200" Grid.Row="1" >
<ItemsControl Name="rectanglesList" Background="AliceBlue">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Y}"/>
<Setter Property="Canvas.Top" Value="{Binding X}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Black">
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="{Binding Color}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
现在,由于画布的高度和宽度属性不包括其子项,Scrollviewer
将无法工作,除非我通过计算子项的高度和宽度之和并将其分配给ItemsControl
来手动更改ItemsControl
高度和宽度
现在的问题是,是否有我丢失的自动执行此操作的属性?您可以使用自定义画布覆盖
MeasureOverride
方法
public class MyCanvas : Canvas
{
protected override Size MeasureOverride(Size constraint)
{
base.MeasureOverride(constraint);
var size = new Size();
foreach (var child in Children.OfType<FrameworkElement>())
{
var x = GetLeft(child) + child.Width;
var y = GetTop(child) + child.Height;
if (!double.IsNaN(x) && size.Width < x)
{
size.Width = x;
}
if (!double.IsNaN(y) && size.Height < y)
{
size.Height = y;
}
}
return size;
}
}
ItemTemplate
将如下所示:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:MyCanvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Black">
<Rectangle Fill="{Binding Color}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
或
您可能还希望将SCrollViewer放入ItemsControl的ControlTemplate中:
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
@Clemens的答案很好。我只是想添加一些上下文,说明为什么在不清楚的情况下有必要这样做
在WPF中,<代码>画布面板在被要求测量自身时不考虑其子元素。父控件负责确保画布的大小适合其包含的项目
在@Clemens提供的子类中,MeasureOverride
中提供了考虑所有子类的逻辑
注意,这将不考虑任何非代码>框架元素< /代码>子。如果您添加了大量的子项,您可能会在布局过程中注意到性能问题。
感谢您的进一步说明,如果您愿意,由于您带来了性能问题,您是否可以提供50000个矩形的解决方案?:-)<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle StrokeThickness="1" Stroke="Black" Fill="{Binding Color}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>