StackPanel:将子元素排列到可沿水平或垂直放置的行。
参考资料:
1. StackPanel类
2. Silverlight学习笔记(九)——RenderTransform特效【五种基本变换】及【矩阵变换MatrixTransform】
3. MatrixTransform矩阵变换
stack表明StackPanel跟栈一样,按顺序压入。StackPanel排列方向分为水平竖直,由Orientation设置,Horizontal(水平)或Vertical(竖直)。如下例所示:
<Grid><StackPanel Height="326" HorizontalAlignment="Left" Margin="30,25,0,0"Name="sp_1" VerticalAlignment="Top" Width="265"Orientation="Horizontal"/><StackPanel Height="326" HorizontalAlignment="Left" Margin="323,25,0,0" Name="sp_2" VerticalAlignment="Top" Width="265" Orientation="Vertical"/>
</Grid>
private void init_sp_1(){for (int i = 0; i < 5; i++){Button btn = new Button();btn.Background = Brushes.LightCyan;btn.Width = 20;btn.Height = (i+1) * 30;btn.Content = i.ToString();this.sp_1.Children.Add(btn);}}private void init_sp_2(){for (int i = 0; i < 5; i++){Button btn = new Button();btn.Background = Brushes.LightCyan;btn.Width = (i + 1) * 30;btn.Height = 20;btn.Content = i.ToString();this.sp_2.Children.Add(btn);}}
运行效果:
但是实际开发过程中,我们通常需要从右往左,从下往上,那如何实现呢?
- 从右往左,好办。只要把StackPanel的FlowDirection属性设置为RightToLeft即可!
- 从下往上,分为前台后台:
前台如下设置:
<Button Content="4" Canvas.Left="125" Canvas.Top="417" Padding="12"RenderTransformOrigin="0.5,0.5"><Button.RenderTransform><ScaleTransform ScaleX="-1"/></Button.RenderTransform>
</Button>
要是动态添加控件的话,后台如下:
private void init_sp_2()
{for (int i = 0; i < 5; i++){Button btn = new Button();btn.Background = Brushes.LightCyan;btn.Width = (i + 1) * 30;btn.Height = 20;btn.Content = i.ToString();ScaleTransform st = new ScaleTransform();st.ScaleX = -1;st.CenterX = btn.Width / 2;st.CenterY = btn.Height / 2;st.ScaleY = -1;btn.SetValue(Button.RenderTransformProperty, st);this.sp_2.Children.Add(btn);}
}
运行结果:
附:RenderTransform(System.Windows.UIElement)特效
- TranslateTransform —— 平面位移变换
- RotationTransform —— 旋转变换
- ScaleTransform —— 缩放变换
- SkewTransform —— 扭曲变换
- TransformGrop —— 组合(组合上述变换效果)变换
- MatrixTransform —— 通过矩阵法算实现复杂变换
1.TranslateTransform
<Canvas Name="canvas_main" Background="Transparent"><Label Name="lb_1" Content="After Change" Width="200" Height="45"HorizontalAlignment="Left" VerticalAlignment="Top"FontSize="17" Canvas.Left="0" Canvas.Top="0" Padding="6"BorderBrush="LightBlue" BorderThickness="2"><Label.RenderTransform><TranslateTransform X="50" Y="80"/></Label.RenderTransform></Label><Label Name="lb_2" Content="Before Change" Width="200" Height="45" HorizontalAlignment="Left" VerticalAlignment="Top"FontSize="17" Canvas.Left="0" Canvas.Top="0" Padding="6"BorderBrush="LightBlue" BorderThickness="2"></Label></Canvas>
运行效果:
2.RotationTransform
<Label.RenderTransform><RotateTransform CenterX="200" CenterY="45" Angle="180"/>
</Label.RenderTransform>
CenterX和CenterY来设置旋转的中心点。这里定为矩形的右下角为旋转点,顺时针旋转180°。
3.ScaleTransform
<Label.RenderTransform><ScaleTransform CenterX="0" CenterY="0" ScaleX="2" ScaleY="1"/>
</Label.RenderTransform>
上面的例子,我发现。如果只改变ScaleX(1是正常状态),ScaleY保持1不变。此时,无论CenterY为何值,都没有影响。由此可见CenterX指定横向拉伸的基准点,这里是X=0这条直线,向右扩张2倍(如果ScaleX为负值,则向左扩张)。同理CenterY指定竖向的基准轴。
4.SkewTransform
<Label.RenderTransform><SkewTransform CenterX="-20" CenterY="0" AngleX="0" AngleY="45"/>
</Label.RenderTransform>
这里,(CenterX,CenterY)=(-20,0)指定了中心点。AngleY=45°,绕Y轴旋转45°,注意此时不是绕X=0旋转,而是绕X=-20旋转。所以在不绕X轴(也就是说AngleX固定)时,改变CenterY不会有影响。和Scale相反。
5.TransformGrop
以上四种变换要是想组合起来使用,就可以用TransformGroup组合起来,否则会报错。
<Label.RenderTransform><TransformGroup><TranslateTransform X="-200" Y="-45"/><ScaleTransform CenterX="100" CenterY="22.5" ScaleX="-1" ScaleY="-1"/></TransformGroup>
</Label.RenderTransform>
6. MatrixTransform
有六个值:
{M11,M12,M21,M22,OffsetX,OffsetY}
看几个例子:
比如现在有一个点(2,5),
这里M11=1,M12=0,M21=0,M22=1,这是它们的默认值,对点的位置没有影响。它们构成这样的一个矩阵:
如果需要位移的话,可以加上偏移OffsetX和OffsetY,于是有这样的公式:
将M11,M12,M21,M22默认值(1,0,0,1)代入:
根据这个公式,我们可以从底层来实现上面几个平移、选择、扭曲的功能。
平移:
<Label.RenderTransform><MatrixTransform Matrix="1,0,0,1,80,30"/>
</Label.RenderTransform>
结论:OffsetX和OffsetY控制水平和竖直方向的偏移。
拉伸:
x方向拉伸了1倍。
<MatrixTransform Matrix="2,0,0,1,0,0"/>
结论:M11控制X方向的伸缩,M22控制Y方向的伸缩。
旋转:
90度旋转:
例如,现在有点(x,y),要求选择90度:
两个向量垂直,则向量积为0,得:
那么究竟M12=1,M21=-1还是M12=-1,M21=1呢?这取决于顺时针旋转还是逆时针旋转。这里M12=1是顺时针,反之为逆时针。
<MatrixTransform Matrix="0,-1,1,0,155,200"/>
这里逆时针旋转90度后,加上Offset后,效果如上。加起来的效果就是沿右上角逆时针旋转90度。
结论:如果Matrix不是按默认值(+-1,0,0,+-1)设置,那么就有可能做旋转操作,几种情况分析如下。
角度 | 原始值 | 顺时针 | 逆时针 |
0 | (x,y) | (x,y)(1,0,0,1) | 同左 |
90 | (x,y) | (y,-x)(0,-1,1,0) | (-y,x)(0,1,-1,0) |
180 | (x,y) | (-x,-y)(-1,0,0,-1) | 同左 |
270 | (x,y) | (-y,x)(0,1,-1,0) | (y,-x)(0,-1,1,0) |