WPF Canvas Scaling/Transform to Fit

本秂侑毒 提交于 2019-12-03 08:48:02

问题


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.

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?

An example of what I'm trying to achieve, I've got A I want to try and get B:

(removed expired link to an 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.

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:

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

回答1:


As your Canvas doesn't seem to have fixed width and height, I would include it into a 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.



来源:https://stackoverflow.com/questions/2236865/wpf-canvas-scaling-transform-to-fit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!