wpf - 无法在画布内居中画布
问题描述
我在 WPF 中有一个视图,我需要在画布中将画布居中。我知道这不是最合适的容器,但我们还有其他组件将出现在这个画布中,它将大大简化我们的工作。
所以基本上,我目前有这段代码:
<Canvas Name="RootContainer" Background="#373B3F" ClipToBounds="True" MouseLeftButtonDown="OnMainCanvasMouseLeftButtonDown">
<Canvas.DataContext>
<local:SomeViewModel/>
</Canvas.DataContext>
<Canvas Name="SomeContainer" Background="#373B3F" MouseMove="OnCanvasMouseMove" MouseWheel="OnCanvasMouseWheel">
<Canvas.Left>
<MultiBinding Converter="{StaticResource CenterValueConverter}">
<Binding ElementName="RootContainer" Path="ActualWidth" />
<Binding ElementName="SomeContainer" Path="ActualWidth" />
</MultiBinding>
</Canvas.Left>
<Canvas.Top>
<MultiBinding Converter="{StaticResource CenterValueConverter}">
<Binding ElementName="RootContainer" Path="ActualHeight" />
<Binding ElementName="SomeContainer" Path="ActualHeight" />
</MultiBinding>
</Canvas.Top>
<ItemsControl ItemsSource="{Binding SomeChilds}" Name="ItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Left}" />
<Setter Property="Canvas.Top" Value="{Binding Top}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource ConventionBasedDataTemplateSelector}"
MouseLeftButtonDown="OnMouseLeftButtonDown" PreviewMouseLeftButtonUp="OnPreviewMouseLeftButtonUp" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Some other controls over here -->
</Canvas>
</Canvas>
这个转换器:
public class CenterValueConverter : IMultiValueConverter
{
public object Convert(object[] values,
Type targetType,
object parameter,
CultureInfo culture)
{
if (values == null || values.Length != 2)
{
return null;
}
double totalWidth = (double)values[0];
double size = (double)values[1];
return totalWidth / 2 - (size / 2);
}
public object[] ConvertBack(object value,
Type[] targetTypes,
object parameter,
CultureInfo culture)
{
throw new NotSupportedException();
}
}
问题是第二个值(SomeContainer.ActualWidth/ActualHeight)总是带有值 0(即使我有一些真实的元素)。
知道为什么以及如何解决这个问题吗?SomeContainer
或者在?中居中的另一种 XAML 方式RootContainer
?
编辑
也许我计划使用这么多的一些额外信息Canvas
。
- 一个
RootContainer
是因为SomeContainer
会有变换(缩放比例)和平移平移 - 我
SomeContainer
猜可能会有所不同 - ItemControls 内的 Canvas 是因为每个元素都会被定位为一个非常具体的位置。
解决方案
我猜你的 ActualHeight/ActualWidth 是 = 0 因为你还没有加载窗口。为了使这些计算考虑到 Canvas 的尺寸,您可以使用“OnContentRendered”事件,该事件将在显示窗口后启动,因此您将显示它们的尺寸。如果你的 Canvas 可能会改变尺寸,你也可以使用SizeChanged
event. 即使我认为这有点复杂,您也可以使用取自Clemen 的答案的XAML 代码:
<Canvas Background="Transparent"
SizeChanged="ViewportSizeChanged"
MouseLeftButtonDown="ViewportMouseLeftButtonDown"
MouseLeftButtonUp="ViewportMouseLeftButtonUp"
MouseMove="ViewportMouseMove"
MouseWheel="ViewportMouseWheel">
<Canvas x:Name="canvas" Width="1000" Height="600">
<Canvas.RenderTransform>
<MatrixTransform x:Name="transform"/>
</Canvas.RenderTransform>
<Ellipse Fill="Red" Width="100" Height="100" Canvas.Left="100" Canvas.Top="100"/>
<Ellipse Fill="Green" Width="100" Height="100" Canvas.Right="100" Canvas.Bottom="100"/>
</Canvas>
</Canvas>
推荐阅读
- python - 如何规范化熊猫数据框中的多列字典
- javascript - ETHERPAD:禁用链接共享
- javascript - 如何在 javascript 中简化嵌套平面图
- r - left_join - 由于类型不兼容而无法加入
- mongodb - 如何将 MongoDB 与 node-red 连接
- r - 回归投资组合超额收益
- rust - Rust 中的类似 Java 枚举的行为
- wxpython - 如何在按钮单击中附加到 wxPython ListCtlr
- r - 使用标签作为新列的值将列表转换为数据框(使用 R)
- php - 在 mysql 中使用 PHP 字符串,isset 无法解决未定义的可变问题