当factor小于1时,缩放以使内容适合Canvas

时间:2016-06-28 14:44:16

标签: wpf canvas scale

使用下面的代码,当scaleX和scaleY大于1时,每个似乎都工作正常(例如,this.Width变为100 - > 100 / 83.25 = 1.20。但是当这些值低于1时(例如,此宽度变为50 - > scaleX = 50 / 83.25 = 0.600)所呈现的球体大于所考虑的球体。

当大小低于画布内容的实际界限时,是否有任何公式可以计算正确的缩放值?

给出以下XAML文件:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:xxx" x:Class="xxx.MainTile"
        Title="Easy uploader" SizeToContent="WidthAndHeight" ResizeMode="NoResize" ShowInTaskbar="False" Icon="quercis.ico" Topmost="True" WindowStyle="None" Loaded="Window_Loaded" SizeChanged="Window_SizeChanged">
    <Grid>
        <local:Tile HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="Tile" >
        </local:Tile>
    </Grid>
</Window>

相应的Tile类:

public partial class Tile : Canvas
{
    public static int MinTileSize = 50;
    private TileSize tileSize = TileSize.Large;

    public delegate void TileSizeChangedDelegate();
    public event TileSizeChangedDelegate TileSizeChanged;
    public TileSize TileSize
    {
        get { return tileSize; }
        set
        {
            TileSize orgTileSize = tileSize;
            tileSize = value;
            //TileCanvas.Width = TileCanvas.Height = 80;
            switch (tileSize)
            {
                case EasyUploader.TileSize.Small: this.Width = MinTileSize; this.Height = MinTileSize; break;
                case EasyUploader.TileSize.Medium: this.Width = 2 * MinTileSize; this.Height = 2 * MinTileSize; break;
                case EasyUploader.TileSize.Wide: this.Width = 4 * MinTileSize; this.Height = 2 * MinTileSize; break;
                case EasyUploader.TileSize.Large: this.Width = 4 * MinTileSize; this.Height = 4 * MinTileSize; break;
            }

            if (this.Parent.GetType() == typeof(MainTile))
            {
                Registry.SetCurrentUserValue("MainTileSize", value.ToString());
            }

            if ((orgTileSize != tileSize) && (TileSizeChanged != null))
                TileSizeChanged();

            double scaleX = this.Width / canvasBounds.Width; //if (scaleX < 1) scaleX = -1 * (canvasBounds.Width / this.Width);
            double scaleY = this.Height / canvasBounds.Height; //if (scaleY < 1) scaleY = -1 * (canvasBounds.Height / this.Height);
            this.RenderTransform = new ScaleTransform(scaleX, scaleY);
        }
    }

    private Rectangle canvasBounds = new Rectangle() { Width = 0, Height = 0 };

    public Tile()
    {
        this.Background = Brushes.Red;

        string xaml = "<Ellipse Name=\"Ellipse\" Width=\"80\" Height=\"80\">" +
        "    <Ellipse.Fill>" +
        "        <RadialGradientBrush RadiusX=\"0.675\" RadiusY=\"0.675\" Center=\"0.644144,0.355856\" GradientOrigin=\"0.644144,0.355856\">" +
        "            <RadialGradientBrush.GradientStops>" +
        "                <GradientStop Color=\"#FFFFFFFF\" Offset=\"0\"/>" +
        "                <GradientStop Color=\"#FF153FC4\" Offset=\"1\"/>" +
        "            </RadialGradientBrush.GradientStops>" +
        "            <RadialGradientBrush.RelativeTransform>" +
        "                <TransformGroup/>" +
        "            </RadialGradientBrush.RelativeTransform>" +
        "        </RadialGradientBrush>" +
        "    </Ellipse.Fill>" +
        "</Ellipse>";

        Canvas canvasFromXaml = (Canvas)XamlReader.Parse("<Canvas xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" + xaml + "</Canvas>");

        double maxHeight = 0;
        double maxWidth = 0;
        while (canvasFromXaml.Children.Count > 0)
        {
            UIElement e = canvasFromXaml.Children[0];
            canvasFromXaml.Children.Remove(e);

            if (double.IsNaN(Canvas.GetLeft(e))) Canvas.SetLeft(e, 0);
            if (double.IsNaN(Canvas.GetTop(e))) Canvas.SetTop(e, 0);

            Canvas.SetTop(e, 0);

            this.Children.Add(e);

            maxWidth = Math.Max((double)e.GetValue(Canvas.WidthProperty) + (double)e.GetValue(Canvas.LeftProperty), maxWidth);
            maxHeight = Math.Max((double)e.GetValue(Canvas.HeightProperty) + (double)e.GetValue(Canvas.TopProperty), maxHeight);
        }

        canvasBounds = new Rectangle() { Width = maxWidth, Height = maxHeight };
    }
}

public enum TileSize
{
    Small, // 50x50
    Medium, // 100x100
    Wide, // 200x100
    Large // 200x200
}

0 个答案:

没有答案