【问题标题】:WPF Canvas Scaling/Transform to FitWPF 画布缩放/变换以适应
【发布时间】:2011-01-15 06:20:19
【问题描述】:

我重新发布这个问题,因为我上次没有得到太多回应,希望重新措辞可能会有所帮助......

基本上我要做的是创建一个数据绑定画布,它将自动缩放其内容以“填充”可用空间。有点像缩放以适应操作。不幸的是,我的 WPF 技能还不是很强大,我正在努力研究如何完成最后一部分。我已经按照一些数据绑定示例来绑定画布,但不确定它是否错误并阻碍了我。

目前我遇到了两个基本问题,具体取决于我尝试解决解决方案的方式:

  • 我不知道如何制作 画布自动重新缩放 如果可能的话,通过 XAML 使用 转变。
  • 我好像不能 参考后面的画布 代码,我猜是因为它的一部分 ItemsControl 的?

我正在努力实现的一个例子,我有 A 我想尝试得到 B:

删除了指向 img 的过期链接

我目前使用的代码非常简单,只需创建具有给定坐标的 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; } }
}

然后 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>

【问题讨论】:

    标签: c# wpf canvas scaletransform


    【解决方案1】:

    由于您的 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>
    

    或者,将整个UserControl 放入ViewBox

    【讨论】:

    • @Mart : 很有趣,看起来和我想要的很接近。如果我按照您的建议更改代码,则会收到 InvalidOperationException “ItemsPanelTemplate 的 VisualTree 必须包含面板。'System.Windows.Controls.Viewbox' 不是面板。”
    • @Mart :如果我按照您的其他建议将我的 AutoResizingCanvas UserControl 包装在视图框中,我的点确实会缩放,但是它们出现在一个奇怪的位置并且我失去了我的背景颜色。见截图:img62.imageshack.us/img62/4481/imagejc.jpg
    • 您的问题来自 Canvas 没有维度的事实。它的父容器使它占据了整个可用空间。如果您知道点的 X 和 Y 的界限,请将它们设置为画布宽度和高度。这样,在 UserControl 或 ItemsControl 周围放置一个 Viewbox 实际上会拉伸它。
    • 我添加了一种新方法来遍历我的 ViewModel 中的所有项目以计算出极值。完成后,我必须再次遍历它们,并调整点以将整个数据集移动到 (0,0) 而不是从 (1,1) 开始。目前正在尝试使用 TranslateTransform 来尝试执行此操作。
    • 您的 PointViewModel 类可用于翻译。这就是 ViewModel 的用途:将您的实际数据转换为视图数据。更改您的 X 和 Y 吸气剂以将值减一。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2011-12-28
    • 1970-01-01
    • 2016-09-30
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多