添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
正直的大蒜  ·  Android ...·  11 月前    · 
寂寞的烤红薯  ·  WPF LiveChart ...·  1 年前    · 

X1,Y1作为起点,X2,Y2作为终点。Stroke(边线)属性的数据类型是Brush,用来填充。

<Window x:Class="WpfApplication1.Window45"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window45" Height="293" Width="437">
        <Line X1="10" Y1="20" X2="260" Y2="20" Stroke="Red" StrokeThickness="10"></Line>
        <Line X1="10" Y1="40" X2="260" Y2="40" Stroke="Orange" StrokeThickness="6"></Line>
        <Line X1="10" Y1="60" X2="260" Y2="60" Stroke="Green" StrokeThickness="3"></Line>
        <Line X1="10" Y1="80" X2="260" Y2="80" Stroke="Purple" StrokeThickness="2"></Line>
        <Line X1="10" Y1="100" X2="260" Y2="100" Stroke="Black" StrokeThickness="1"></Line>
        <Line X1="10" Y1="120" X2="260" Y2="120" StrokeDashArray="3" Stroke="Black" StrokeThickness="1"></Line>
        <Line X1="10" Y1="140" X2="260" Y2="140" StrokeDashArray="5" Stroke="Black" StrokeThickness="1"></Line>
        <Line X1="10" X2="260" Y1="160" Y2="160" Stroke="Black" StrokeThickness="6" StrokeEndLineCap="Flat"></Line>
        <Line X1="10" X2="260" Y1="180" Y2="180" Stroke="Black" StrokeThickness="8" StrokeEndLineCap="Triangle"></Line>
        <Line X1="10" X2="260" Y1="200" Y2="200" StrokeEndLineCap="Round" StrokeThickness="10">
            <Line.Stroke>
                <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
                    <GradientStop Color="Blue"></GradientStop>
                    <GradientStop Offset="1" Color="Red"></GradientStop>
                </LinearGradientBrush>
            </Line.Stroke>
        </Line>
    </Grid>
</Window>

Rectangle

矩形由Stroke(边线)和Fill(填充)构成。数据类型均为Brush,常见的Brush子类有:

  • SolidColorBrush:实心画刷,常用Red、Blue等字符串赋值
  • LinearGradientBrush:线性渐变画刷
  • RadialGradentBrush:径向渐变画刷
  • ImageBrush:图片作为内容
  • DrawingBrush:矢量图或者位图填充
  • VisualBrush:每个控件的可视化形象可以通过Visual类的方法获得,并用该形象进行填充,这就是VisualBrush。如:控件被拖拽过程中显示一个幻影,这个幻影就可以使用VisualBrush来填充。
  • <Window x:Class="WpfApplication1.Window46"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window46" Height="390" Width="600">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="180" />
                <ColumnDefinition Width="10" />
                <ColumnDefinition Width="180" />
                <ColumnDefinition Width="10" />
                <ColumnDefinition Width="180*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="160" />
                <RowDefinition Height="10" />
                <RowDefinition Height="160" />
            </Grid.RowDefinitions>
            <!--实心填充-->
            <Rectangle Grid.Row="0" Grid.Column="0" Stroke="Black" Fill="LightBlue"></Rectangle>
            <!--线性渐变-->
            <Rectangle Grid.Row="0" Grid.Column="2">
                <Rectangle.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="#FFB6F8F1" Offset="0"></GradientStop>
                        <GradientStop Color="#FF0082BD" Offset="0.25"></GradientStop>
                        <GradientStop Color="#FF95DEFF" Offset="0.6"></GradientStop>
                        <GradientStop Color="#FF004F72" Offset="1"></GradientStop>
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <!--径向渐变-->
            <Rectangle Grid.Row="0" Grid.Column="4">
                <Rectangle.Fill>
                    <RadialGradientBrush>
                        <GradientStop Color="#FFB6F8F1" Offset="0"></GradientStop>
                        <GradientStop Color="#FF0082BD" Offset="0.25"></GradientStop>
                        <GradientStop Color="#FF95DEFF" Offset="0.75"></GradientStop>
                        <GradientStop Color="#FF004F72" Offset="1.5"></GradientStop>
                    </RadialGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <!--图片填充-->
            <Rectangle Grid.Row="2" Grid.Column="0">
                <Rectangle.Fill>
                    <ImageBrush ImageSource="./01077_1.png" Viewport="0,0,0.3,0.3" TileMode="Tile">
                    </ImageBrush>
                </Rectangle.Fill>
            </Rectangle>
            <!--矢量图-->
            <Rectangle Grid.Row="2" Grid.Column="2">
                <Rectangle.Fill>
                    <DrawingBrush Viewport="0,0,0.2,0.2" TileMode="Tile">
                        <DrawingBrush.Drawing>
                            <GeometryDrawing Brush="LightBlue">
                                <GeometryDrawing.Geometry>
                                    <EllipseGeometry RadiusX="10" RadiusY="10"></EllipseGeometry>
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>
                        </DrawingBrush.Drawing>
                    </DrawingBrush>
                </Rectangle.Fill>
            </Rectangle>
            <!--无填充,使用线性渐变填充边框-->
            <Rectangle Grid.Row="2" Grid.Column="5" StrokeThickness="10">
                <Rectangle.Stroke>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="White" Offset="0.3"></GradientStop>
                        <GradientStop Color="Blue" Offset="1"></GradientStop>
                    </LinearGradientBrush>
                </Rectangle.Stroke>
            </Rectangle>
        </Grid>
    </Window>
    

    使用visualBrush的案例

    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="160" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="160" />
        </Grid.ColumnDefinitions>
        <StackPanel Background="White" x:Name="spleft">
            <Button Height="40" Content="OK" x:Name="btnReal" Click="btnReal_Click"></Button>
        </StackPanel>
        <Button Grid.Column="1" Content=">>" Margin="5,0"></Button>
        <StackPanel Grid.Column="2" Background="White" x:Name="spRight">
        </StackPanel>
    </Grid>
    
    double o = 1;//不透明度指数
    private void btnReal_Click(object sender, RoutedEventArgs e)
        VisualBrush vb = new VisualBrush(this.btnReal);
        Rectangle rtg = new Rectangle();
        rtg.Width = btnReal.Width;
        rtg.Height = btnReal.Height;
        rtg.Fill = vb;
        rtg.Opacity = o;
        o -= 0.2;
        this.spRight.Children.Add(rtg);
    

    Ellipse

    <Ellipse Height="140" Name="ellipse1" Stroke="Gray" Width="140" Cursor="Hand" ToolTip="A Ball"> <Ellipse.Fill> <RadialGradientBrush GradientOrigin="0.2,0.8" RadiusX="0.75" RadiusY="0.75"> <RadialGradientBrush.RelativeTransform> <TransformGroup> <RotateTransform Angle="90" CenterX="0.5" CenterY="0.5"></RotateTransform> </TransformGroup> </RadialGradientBrush.RelativeTransform> <GradientStop Color="#FFFFFFFF" Offset="0" /> <GradientStop Color="#FF444444" Offset="0.66" /> <GradientStop Color="#FF999999" Offset="1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> </Grid>

    路径可以替代其他几种图形,并且可以将直线、圆弧等基本元素结合形成复杂的图形。Path最重要的属性是Data,其数据类型为Geometry抽象类。Geometry子类包括:

  • LineGeometry:直线几何
  • RectangleGeometry:矩形几何
  • EllipseGeometry:椭圆几何
  • PathGeometry:路径几何
  • StreamGeometry:PathGeometry的轻量替代类,不支持Binding、动画等
  • CombinedGeometry:多个基本图形的组合,形成一个几何图形
  • GeometryGroup:多个基本图形的组合,形成一个几何图形组
  • 与Line、Rectangle等的区别:Line等可以独立存在,而Geometry只能结合其他几何,不能独立存在。

    <Grid.RowDefinitions> <RowDefinition Height="160" /> <RowDefinition Height="160" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="160" /> <ColumnDefinition Width="160" /> </Grid.ColumnDefinitions> <!--直线--> <Path Stroke="Blue" StrokeThickness="2" Grid.Row="0" Grid.Column="0"> <Path.Data> <LineGeometry StartPoint="0,0" EndPoint="160,160"></LineGeometry> </Path.Data> </Path> <!--矩形路径--> <Path Stroke="Orange" Fill="Yellow" Grid.Row="0" Grid.Column="1"> <Path.Data> <RectangleGeometry Rect="20,20,120,120" RadiusX="10" RadiusY="10"></RectangleGeometry> </Path.Data> </Path> <!--椭圆路径--> <Path Stroke="Green" Fill="LawnGreen" Grid.Column="0" Grid.Row="1"> <Path.Data> <EllipseGeometry Center="80,80" RadiusX="60" RadiusY="40"></EllipseGeometry> </Path.Data> </Path> <!--自定义路径--> <Path Stroke="Yellow" Fill="Orange" Grid.Row="1" Grid.Column="1"> <Path.Data> <PathGeometry> <!--Path.Figures属性可以容纳Figuress对象,PathFigure的Segments属性可以容纳各种线段用于形复杂的图形--> <PathGeometry.Figures> <PathFigure StartPoint="25,140" IsClosed="True"> <PathFigure.Segments> <LineSegment Point="20,40"></LineSegment> <LineSegment Point="40,110"></LineSegment> <LineSegment Point="50,20"></LineSegment> <LineSegment Point="80,110"></LineSegment> <LineSegment Point="110,20"></LineSegment> <LineSegment Point="120,110"></LineSegment> <LineSegment Point="140,40"></LineSegment> <LineSegment Point="135,140"></LineSegment> </PathFigure.Segments> </PathFigure> </PathGeometry.Figures> </PathGeometry> </Path.Data> </Path> </Grid>

    PathFigure的Segments属性所包含的线段:

  • LineSegment:直线
  • ArcSegment:圆弧
  • BezierSement:三次方贝塞尔曲线
  • QuadraticBezierSement:二次方贝塞尔曲线
  • PolyLineSegment:多直线段
  • PolyBezierSegment:多三次方贝塞尔曲线
  • PolyQuadraticBezierSement:多二次方贝塞尔曲线
  • 注意:绘制上面的线段是没有起点的,起点就是上一个线段的终点,第一个线段的起点是PathFigure的StartPoint。

    路径标记法

    Path非常强大,但是上面的标签式的语法过于繁琐。WPF提供路径标记法来替代标签式语法。、

    路径标记法就是各种线段的简记法,如<LineSegment Point="15,15">可以改为L, 15,15。除此之外,路径标记法还增加了一些实用的命令,如H 80,代表从当前点画一条水平直线,横坐标终点是80。

    使用路径标记法的步骤分为三步移动至起点->绘图->闭合图形,常用命令如下:

    命令用途语法示例标签式语法分类
    M移动到起点M 起始点M 10,10移动命令
    L绘制直线L 终点L 150,30绘图命令
    H绘制水平直线H 终点横坐标H 180绘图命令
    V绘制数值线V 终点纵坐标V 180绘图命令
    A绘制圆弧A 母椭圆尺寸 旋转角度是否大弧 顺/逆 终点A 180,80 45 1 1 150,150绘图命令
    C三次方贝塞尔曲线C 控制点1 控制点2 终点C 250,0 50,200 300,200绘图命令
    Q二次方贝塞尔Q 控制点1 终点Q 150,100 300,200绘图命令
    S平滑三次贝塞尔S 控制点2 终点S 100,200 200,300绘图命令
    T平滑二次方贝塞尔T 终点T 400,200绘图命令
    Z闭合图形ZM 0,0 L 40,80 L80,40 Z关闭命令

    不规则窗体和控件仅需使用Clip属性就可以做到。

    <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
        <Path Stroke="Orange" Fill="Yellow" x:Name="clipPath0" Visibility="Hidden" Data="M 55,100 A 50,50 0 1 1 100,60 A 110,95 0 0 1 200,60 A 50,50 0 1 1 250,100 A 110,95 0 1 1 55,100 Z">
        </Path>
        <Button Content="Clip" Width="80" Height="25" Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center"></Button>
    </Grid>
    
    private void Button_Click(object sender, RoutedEventArgs e)
        this.Clip = clipPath0.Data;
    

    图形的效果与滤镜

    简单易用的BitmapEffect

    WPF早期的效果属性,是使用CPU来进行运算,会导致程序卡顿,不建议使用

    BitmapEffect派生类:

  • BevelBitmapEffect:斜角效果
  • BitmapEffectGroup:符合效果
  • BlurBitmapEffect:模糊效果
  • DropShadowBitmapEffect:投影效果
  • EmbossBitmapEffect:浮雕效果
  • OuterGlowBitmapEffect:外发光效果
  • <Button Content="Click Me" Grid.Column="0" Grid.Row="0" Margin="20">
        <Button.BitmapEffect>
            <BlurBitmapEffect Radius="3"/>
        </Button.BitmapEffect>
    </Button>
    

    Effect

    采用GPU对UI进行渲染,功能强大。

    Effect具有如下派生类

  • BlurEffect:模糊效果
  • DropShadowEffect:投影效果
  • ShaderEffect:着色器(抽象类)
  • 图形的变形

    WPF中的变形与UI元素是分开的,可以单独设置一个旋转45度的变形,然后把该变形赋值给不同的UI元素。

    控制变形的属性有两个:

  • RenderTransform:呈现变形
  • LayoutTransform:布局变形
  • 这两个属性的值类型为Transform抽象类型,常见的派生类有:

  • MatrixTransform:矩阵变形
  • RotateTransform:旋转变形
  • ScaleTransform:缩放变形
  • SkewTransform:拉伸变形
  • TranslateTransform:偏移变形
  • TransformGroup:变形组
  • 呈现变形(Render Transform)

    让UI元素呈现出来的属性与本来的属性不一样,如按钮本来在左上角,但是让他呈现在右下角,且旋转45度。

    <Window x:Class="WpfApplication1.Window59"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window59" Height="334" Width="485">
        <Grid Margin="10" Background="AliceBlue">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto">
                </ColumnDefinition>
                <ColumnDefinition Width="*">
                </ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto">
                </RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Button Width="80" Height="80" Content="OK" Background="Red" Foreground="White">
                <Button.RenderTransform>
                    <!--复合变形-->
                    <TransformGroup>
                        <!--旋转变形-->
                        <RotateTransform CenterX="40" CenterY="40" Angle="45"></RotateTransform>
                        <!--偏移变形-->
                        <TranslateTransform X="300" Y="150"></TranslateTransform>
                    </TransformGroup>
                </Button.RenderTransform>
            </Button>
        </Grid>
    </Window>
    

    在Grid中划分了2行2列,第一行第一列根据Button自动调整,然后利用变形天正button的位置和角度,但是Button本身的位置属性却没有改变,这样仅仅改变button的显示效果会极大提高效率。所以在做动画的时候一定要用Render Transform。

    与呈现变形不同,布局变形会影响整个窗体的布局导致重新测算,所以会影响程序的性能。布局变形一般用在静态变形上。

    实现文字纵向排列

  • 使用呈现变形
  • <Grid x:Name="titleBar" Background="LightBlue">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock FontSize="24" Text="Hello Transformer" VerticalAlignment="Bottom" HorizontalAlignment="Center">
            <TextBlock.LayoutTransform>
                <RotateTransform Angle="-90"></RotateTransform>
            </TextBlock.LayoutTransform>
        </TextBlock>
    </Grid>
    

    看上去实现了纵向排列,但事实上TextBox本身属性没有变,所以Grid的第一列宽度任然没有变。

  • 使用布局变形
  • <TextBlock.LayoutTransform>
        <RotateTransform Angle="-90"></RotateTransform>
    </TextBlock.LayoutTransform>
    
    <TextBlock.LayoutTransform>
        <RotateTransform Angle="-90"></RotateTransform>
    </TextBlock.LayoutTransform>
    

    此时,Grid的第一列宽度改变。

    步_步_为营 软件开发工程师 @ 中核集团
    粉丝