C# WPF 画布缩放/变换以适合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2236865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Canvas Scaling/Transform to Fit
提问by Ian
I'm reposting this question as I didn't get much of a response last time, hopefully a bit of re-wording might help...
我正在重新发布这个问题,因为上次我没有得到太多回应,希望一些重新措辞可能会有所帮助......
Essentially what I'm trying to do is to create a databound canvas, that will automatically scale its contents to 'fill' up the available space. Sort of like a zoom to fit operation. Unfortunately my WPF skills aren't yet very strong, and I'm struggling to work out how to do this last part. I've followed some databinding examples to get the canvas bound, but not sure if maybe its wrong and hindering me.
本质上,我要做的是创建一个数据绑定画布,它将自动缩放其内容以“填充”可用空间。有点像缩放以适应操作。不幸的是,我的 WPF 技能还不是很强,我正在努力弄清楚如何完成最后一部分。我遵循了一些数据绑定示例来绑定画布,但不确定它是否错误并阻碍了我。
I've got two basic problems at the moment depending on the way I try and tackle the solution, either:
根据我尝试解决解决方案的方式,我目前有两个基本问题:
- I don't know how to make the canvas re-scale automatically through XAML if its possible using a transform.
- I can't seem to reference the canvas in the behind code, I'm guessing because its part of an ItemsControl?
- 如果可能的话,我不知道如何通过 XAML 使画布自动重新缩放。
- 我似乎无法在后面的代码中引用画布,我猜是因为它是 ItemsControl 的一部分?
An example of what I'm trying to achieve, I've got A I want to try and get B:
我正在努力实现的一个例子,我有 AI 想要尝试获得 B:
(removed expired link to an img)
(删除了指向 img 的过期链接)
The code I'm currently using is pretty simple, just creating 4 dots with a given co-ordinate, and a another view model to wrap these up in.
我目前使用的代码非常简单,只需创建具有给定坐标的 4 个点,并使用另一个视图模型来包装这些点。
public class PointCollectionViewModel
{
private List<PointViewModel> viewModels;
public PointCollectionViewModel()
{
this.viewModels = new List<PointViewModel>();
this.viewModels.Add(new PointViewModel(new Point(1, 1)));
this.viewModels.Add(new PointViewModel(new Point(9, 9)));
this.viewModels.Add(new PointViewModel(new Point(1, 9)));
this.viewModels.Add(new PointViewModel(new Point(9, 1)));
}
public List<PointViewModel> Models
{
get { return this.viewModels; }
}
}
public class PointViewModel
{
private Point point;
public PointViewModel(Point point)
{
this.point = point;
}
public Double X { get { return point.X; } }
public Double Y { get { return point.Y; } }
}
Then the PointCollectionViewModel is used as the DataContent for my AutoResizingCanvas, which has the following XAML to implement the binding:
然后 PointCollectionViewModel 用作我的 AutoResizingCanvas 的 DataContent,它具有以下 XAML 来实现绑定:
<UserControl x:Class="WpfCanvasTransform.AutoResizingCanvas"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCanvasTransform"
x:Name="parent">
<ItemsControl x:Name="itemsControl" ItemsSource="{Binding Path=Models}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="canvas" Background="DarkSeaGreen" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1" />
</Canvas.LayoutTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:PointViewModel}">
<Ellipse Width="3" Height="3" Fill="Red"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}"/>
<Setter Property="Canvas.Left" Value="{Binding Path=X}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</UserControl>
采纳答案by Mart
As your Canvas
doesn't seem to have fixed width and height, I would include it into a Viewbox
:
由于您Canvas
似乎没有固定的宽度和高度,我会将它包含在一个Viewbox
:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Viewbox Stretch="Uniform">
<Canvas x:Name="canvas" Background="DarkSeaGreen">
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1" />
</Canvas.LayoutTransform>
</Canvas>
</Viewbox>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Alternatively, place your entire UserControl
into a ViewBox
.
或者,将您的整个文件UserControl
放入ViewBox
.