WPF:使用设计的矢量图像作为WPF中的控件模板

时间:2009-07-23 19:56:54

标签: wpf templates graphics

我正在探索在我的WPF应用程序中使用专业设计的矢量图像作为ControlTemplates的想法。我们的想法是制作几种类型的控件,每种控件都有不同的视觉设计,然后可以拖放。这与视觉设计师(a'la visio)

的用例完全相同

我有以下XAML。它定义了一个目标类型为Button的控件模板,我有一个使用该模板的Button。我想知道的是如何修改此模板,以便它只使用Button的高度和宽度。在我看来好像模板相对于按钮的左上角呈现自己(如果我移动按钮,图像移动)但它没有考虑按钮的尺寸,所以它保持其“设计”尺寸无论我做什么。

<Window x:Class="Euphrosyne.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
    <ControlTemplate TargetType="{x:Type Button}" x:Key="PresentBox">

        <Canvas Name="svg2" >
            <Canvas.Resources/>
            <Canvas Name="layer1">
                <Path Name="path2385" Fill="#D45500" Stroke="#FF000000" StrokeThickness="1px" StrokeLineJoin="Miter" StrokeEndLineCap="Flat" Data="M 110 82.362183 A 40 30 0 1 1 39.041709 63.365048 L 70 82.362183 z"/>
                <Path Name="path2387" Fill="#FF0000" Data="M 100 100 L 79.96762 89.419767 L 59.895213 99.923868 L 63.767267 77.602471 L 47.574559 61.758424 L 69.999999 58.543274 L 80.064762 38.247014 L 90.052393 58.581339 L 112.46547 61.881608 L 96.212721 77.664061 L 100 100 z"/>
                <Path Name="path2389" Fill="#C83737" Data="M 100 40.000002 L 97.601178 65.149257 L 116.9586 81.382849 L 92.298963 86.872981 L 82.841672 110.29944 L 70 88.543275 L 44.797648 86.788031 L 61.520697 67.85185 L 55.402078 43.340588 L 78.579163 53.393551 L 100 40.000002 z">
                    <!--path-->
                </Path>
            </Canvas>
        </Canvas>

    </ControlTemplate>
</Window.Resources>
<Grid>
    <Button Template="{StaticResource PresentBox}" >Hi there</Button>
</Grid>
</Window>

3 个答案:

答案 0 :(得分:1)

将画布包裹在Viewbox中。 Canvas不会将自己的维度与其内容的维度相关联。因此,您可以看到内容随Canvas移动,但不会调整大小。 Viewbox通过在其自身尺寸更改时拉伸其内容来增强Canvas的行为。您可以控制Viewbox的行为,例如水平,垂直或两者都拉伸。不幸的是,没有豪华轿车拉伸,这对UI控件来说很不错。

这是它的外观。请注意,我猜测宽度和高度。它们应该与实际路径匹配。您还应确保路径相对于X和Y轴刷新,以避免留下意外的边距。

<Viewbox Name="viewbox1"
         Height="200" Width="200"
         HorizontalAlignment="Left" VerticalAlignment="Top"
         Stretch="Fill">
    <Canvas Name="layer1">
        <Path Name="path2385" Fill="#D45500" Stroke="#FF000000" StrokeThickness="1px" StrokeLineJoin="Miter" StrokeEndLineCap="Flat" Data="M 110 82.362183 A 40 30 0 1 1 39.041709 63.365048 L 70 82.362183 z"/>
        <Path Name="path2387" Fill="#FF0000" Data="M 100 100 L 79.96762 89.419767 L 59.895213 99.923868 L 63.767267 77.602471 L 47.574559 61.758424 L 69.999999 58.543274 L 80.064762 38.247014 L 90.052393 58.581339 L 112.46547 61.881608 L 96.212721 77.664061 L 100 100 z"/>
        <Path Name="path2389" Fill="#C83737" Data="M 100 40.000002 L 97.601178 65.149257 L 116.9586 81.382849 L 92.298963 86.872981 L 82.841672 110.29944 L 70 88.543275 L 44.797648 86.788031 L 61.520697 67.85185 L 55.402078 43.340588 L 78.579163 53.393551 L 100 40.000002 z"/>
    </Canvas>
</Viewbox>

答案 1 :(得分:1)

通常Canvas不尊重父控件的大小,所以如果用网格替换Canvas,你可以将Button大小放到controltemplate里面的Paths上。

    <Grid x:Name="layer1" Width="Auto" Height="Auto">
                <Path x:Name="path2385" Fill="#D45500" Stroke="#FF000000" StrokeThickness="1px" StrokeLineJoin="Miter" StrokeEndLineCap="Flat" Data="M 110 82.362183 A 40 30 0 1 1 39.041709 63.365048 L 70 82.362183 z" Margin="0,0,6.459,49.147" d:LayoutOverrides="Width, Height"/>
                <Path x:Name="path2387" Fill="#FF0000" Data="M 100 100 L 79.96762 89.419767 L 59.895213 99.923868 L 63.767267 77.602471 L 47.574559 61.758424 L 69.999999 58.543274 L 80.064762 38.247014 L 90.052393 58.581339 L 112.46547 61.881608 L 96.212721 77.664061 L 100 100 z" Margin="0,0,4.493,62" d:LayoutOverrides="Width, Height"/>
                <Path x:Name="path2389" Fill="#C83737" Data="M 100 40.000002 L 97.601178 65.149257 L 116.9586 81.382849 L 92.298963 86.872981 L 82.841672 110.29944 L 70 88.543275 L 44.797648 86.788031 L 61.520697 67.85185 L 55.402078 43.340588 L 78.579163 53.393551 L 100 40.000002 z" Margin="0,0,0,51.7" d:LayoutOverrides="Width, Height">
                    <!--path-->
                </Path>
    </Grid>

否则你可以使用TemplateBinding,它可以将Button的属性赋予controltemplate。例如。

 Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">

如果你根本不能删除Canvas,那么就像Oren上面提到的那样使用它周围的ViewBox

答案 2 :(得分:-1)

您可以将Path.RenderTransform设置为自定义ScaleTransform,以将子元素缩放为父级宽度/高度。