定义行和列
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition><!--占总高度的2/10-->
<RowDefinition Height="5*"></RowDefinition><!--占总高度的5/10-->
<RowDefinition Height="3*"></RowDefinition><!--占总高度的3/10-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/><!--占200px宽度-->
<ColumnDefinition Width="*"/><!--占剩余宽度-->
<ColumnDefinition Width="Auto"/><!--占正好占用的宽度-->
<ColumnDefinition Width="300"/><!--占300px宽度-->
</Grid.ColumnDefinitions>
</Grid>
定义按钮
- 设置偏移
HorizontalAlignment
和HorizontalContentAlignment
: Left、Center、Right、Stretch(拉伸以占满整个空间)VerticalAlignment
和VerticalContentAlignment
: Top、Center、Bottom、Stretch
- 设置占行、列
Grid.Row="0",Grid.Column="0"
:占第一行、第一列Grid.Row="1",Gird.RowSpan="2"
:占第二行和第三行
- 设置边距
Margin="256,30,0,0"
: 左上右下Margin="10"
: 四周都为10pxMargin="10,20"
:左右为10px,上下为20pxPadding
:设置内边距
- 显示”<”和”>”
<
: <>
: >
- 设置文本
FontFamily="宋体,Times New Roman"
:设置字体为宋体,如果语言不支持宋体,则使用新罗马字体FontSize="16"
:设置字体大小为16pxFontStyle="Italic"
:设置字体样式为斜体FontWeight="Bold"
:设置字体加粗FontStretch="Normal"
:设置字体不拉伸
- 设置按钮标记
Cursor="Help"
:设置按钮为帮助CaretBrush="white"
:设置光标为白色
<Button x:Name="Login" Content="<登录>" HorizontalAlignment="Left" Margin="256,30,0,0" Grid.Row="1" Padding="10" VerticalAlignment="Top" Width="75" Grid.ColumnSpan="2"/>
定义输入框
- 文本包装方式
TextWrapping
: NoWrap(不换行)、Wrap(换行)、WrapWithOverflow(换行,但是如果遇到一个单词不够放置,允许单词超出边界)xml:space="preserve"
:保留输入的空格
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="55,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" xml:space="preserve">空格啊" "你看</TextBox>
定义边框
BorderBrush
: 定义边框颜色BorderThickness
: 定义边框粗细CornerRadius
: 定义圆角
<Border BorderBrush="Silver" BorderThickness="2" Name="border1" Padding="10" CornerRadius="10">
<StackPanel Name="stackPanel1" Orientation="Vertical">
<Label x:Name="label" Content="Label"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left"/>
<Button x:Name="button1" Content="Button" VerticalAlignment="Center"/>
<Button x:Name="button2" Content="Button" Margin="10,10,10,10" MinWidth="100" MaxWidth="200"/>
<Button x:Name="button3" Content="Button"/>
</StackPanel>
</Border>
StackPanel
特点:一个控件占一排或者一列
- 设置控件放置方向
Orientation
: Vertical(默认值)、Horizontal
- 设置控件最小、最大宽高
MinWidth
: 最小宽度MaxWidth
: 最大宽度MinHeight
:最小高度MaxHeight
: 最大高度
<StackPanel Name="stackPanel" Orientation="Vertical">
<Label x:Name="label" Content="Label"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left"/>
<Button x:Name="button1" Content="Button" VerticalAlignment="Center"/>
<Button x:Name="button2" Content="Button" Margin="10,10,10,10" MinWidth="100" MaxWidth="200"/>
<Button x:Name="button3" Content="Button"/>
</StackPanel>
DockPanel
特点:可以使控件占满自己呆的空间
-LastChildFill(最后一个元素占满剩余空间)
:true(默认值)、false
- ###### 设置控件位置
-DockPanel.Dock
: Left、Top、Right、Bottom
<DockPanel Name="dockPanel" LastChildFill="True">
<Button x:Name="button1" Content="Top" DockPanel.Dock="Top" VerticalAlignment="Top" />
<Button x:Name="button4" Content="Bottom" DockPanel.Dock="Bottom" VerticalAlignment="Top"/>
<Button x:Name="button2" Content="Left" DockPanel.Dock="Left" Width="75"/>
<Button x:Name="button" Content="Right" DockPanel.Dock="Right" Width="75"/>
<Button x:Name="button3" Content="Center"/>
</DockPanel>
WrapPanel
特点:所有控件从第一排挨着进行排列,满了再跳到下一排。
<WrapPanel Name="wrapPanel" Orientation="Horizontal">
<Button x:Name="button" Content="Button" Width="75" VerticalAlignment="Top"/>
<Button x:Name="button1" Content="Button" Width="75" Height="75"/>
<Button x:Name="button2" Content="Button" Width="308" VerticalAlignment="Bottom"/>
<Button x:Name="button3" Content="Button" Width="75" Height="68"/>
</WrapPanel>
Grid
特点: 其实就是一个表格
-ShowGridLines
: true(显示表格线)、false(默认)
-UseLayoutRounding
: true(对小数四舍五入到整数,防止边缘模糊)、false(默认)
<Grid ShowGridLines="False" UseLayoutRounding="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="50"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="2*" MinWidth="50"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button x:Name="button" Content="LeftTop" Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Margin="3"/>
<Button x:Name="button1" Content="CenterTop" Grid.Row="0" Grid.Column="2" Margin="3" />
<Button x:Name="button2" Content="RightTop" Grid.Row="0" Grid.Column="3" Margin="3"/>
<Button x:Name="button5" Content="RightBottom" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Margin="3"/>
<GridSplitter Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="3" />
</Grid>
Canvas
基于坐标的面板
-Canvas.ZIndex
: 设置三维高度
- ###### 设置边距
-Canvas.Left,Canvas.Top
:左、上
-Canvas.Left,Canvas.Bottom
:左、下
-Canvas.Right,Canvas.Top
:右、上
-Canvas.Right,Canvas.Bottom
:右、下
<Canvas Name="canvas">
<Button x:Name="button" Content="Button" Canvas.Left="275" Canvas.Top="142" Width="75" Click="button_Click"/>
<DataGrid x:Name="dataGrid" Canvas.Left="161" Canvas.Top="82" Height="50" Width="104"/>
<Button x:Name="button1" Content="上层" Canvas.ZIndex="1" Canvas.Left="172" Canvas.Top="96" Width="75"/>
</Canvas>
InkCanvas
墨水面板
- 通过EditingMode
进行面板方式的选择
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="261*"/>
<ColumnDefinition Width="256*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.ColumnSpan="2">
<ComboBox Name="editingMode" Margin="5" SelectionChanged="editingMode_SelectionChanged"></ComboBox>
</StackPanel>
<InkCanvas Grid.Row="1" EditingMode="None" Grid.ColumnSpan="2" Name="inkCanvas">
<Button x:Name="button" Content="Button" InkCanvas.Left="50" InkCanvas.Top="100" Height="22" Width="45"/>
</InkCanvas>
</Grid>
路由事件
直接路由事件
特点:起源于一个元素,并不能传递给其他元素。
-MouseEnter
事件就是直接路由事件
冒泡路由事件
特点:向上传递路由信息
-MouseUp
=”Window_MouseUp”
<!--冒泡路由-->
<Window x:Class="MyEighthWPFDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyEighthWPFDemo"
mc:Ignorable="d"
Title="MainWindow" Width="525" MouseUp="Window_MouseUp">
<Grid Margin="3" MouseUp="Window_MouseUp">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" MouseUp="Window_MouseUp" HorizontalAlignment="Left">
<StackPanel MouseUp="Window_MouseUp">
<TextBlock Margin="3" MouseUp="Window_MouseUp">
Image and Picture lable
</TextBlock>
<Image Source="C:\Users\Administrator\Pictures\2.jpg" Width="100px" Height="100px" Stretch="None" MouseUp="Window_MouseUp" />
<TextBlock Margin="3" MouseUp="Window_MouseUp">
Courtesy of the stackPanel
</TextBlock>
</StackPanel>
</Label>
<ListBox Margin="5" Name="lstMessage" Grid.Row="1"></ListBox>
<CheckBox Margin="5" Grid.Row="2" Name="chkHandle">Handle first envent</CheckBox>
<Button Click="cmdClear_Click" Grid.Row="3" HorizontalAlignment="Center" Margin="5" Padding="3">Clear List</Button>
</Grid>
</Window>
private void Window_MouseUp(object sender, RoutedEventArgs e)
{
//冒泡路由,向上传递 隧道路由,向下传递 隧道事件总是在冒泡事件之前触发
eventCounter++;
string message = $"{eventCounter.ToString()}:\r\n Sender: {sender.ToString()}\r\n Source: {e.Source}\r\n Original Source: {e.OriginalSource} Event: {e.RoutedEvent}";
lstMessage.Items.Add(message);
e.Handled = (bool)chkHandle.IsChecked; //选择了(true)就不再传递
}
隧道路由事件
特点:向下传递路由信息
-PreviewKeyDown
=”Window_MouseUp”
<Window x:Class="MyEighthWPFDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyEighthWPFDemo"
mc:Ignorable="d"
Title="MainWindow" Width="525" PreviewKeyDown="Window_MouseUp">
<Grid Margin="3" PreviewKeyDown="Window_MouseUp">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" PreviewKeyDown="Window_MouseUp" HorizontalAlignment="Left">
<StackPanel PreviewKeyDown="Window_MouseUp">
<TextBlock Margin="3" PreviewKeyDown="Window_MouseUp">
Image and Picture lable
</TextBlock>
<Image Source="C:\Users\Administrator\Pictures\2.jpg" Width="100px" Height="100px" Stretch="None" PreviewKeyDown="Window_MouseUp" />
<TextBox Margin="3" PreviewKeyDown="Window_MouseUp" />
</StackPanel>
</Label>
<ListBox Margin="5" Name="lstMessage" Grid.Row="1"></ListBox>
<CheckBox Margin="5" Grid.Row="2" Name="chkHandle">Handle first envent</CheckBox>
<Button Click="cmdClear_Click" Grid.Row="3" HorizontalAlignment="Center" Margin="5" Padding="3">Clear List</Button>
</Grid>
</Window>
private void Window_MouseUp(object sender, RoutedEventArgs e)
{
//冒泡路由,向上传递 隧道路由,向下传递 隧道事件总是在冒泡事件之前触发
eventCounter++;
string message = $"{eventCounter.ToString()}:\r\n Sender: {sender.ToString()}\r\n Source: {e.Source}\r\n Original Source: {e.OriginalSource} Event: {e.RoutedEvent}";
lstMessage.Items.Add(message);
e.Handled = (bool)chkHandle.IsChecked; //选择了(true)就不再传递
}
键盘事件
特点:根据键盘的动作做出相应的行为
-Focusable="True"
:设置控件能够获取焦点
-TabIndex="0"
:设置控件能够使用Tab键获取焦点的排名,从0开始
-PreviewKeyDown="KeyEvent"
:按键按下前事件
-KeyDown="KeyEvent"
:按键按下时事件
-PreviewTextInput="TextInput"
:文本输入前事件
-TextChanged="TextBox_TextChanged"
:文本输入时事件
-PreviewKeyUp="KeyEvent"
:按键升起前事件
-KeyUp="KeyEvent"
:按键升起时事件
<TextBox Focusable="True" TabIndex="0" PreviewKeyDown="KeyEvent" KeyDown="KeyEvent" PreviewTextInput="TextInput" PreviewKeyUp="KeyEvent" KeyUp="KeyEvent" TextChanged="TextBox_TextChanged"/>
鼠标事件
特点:根据鼠标的动作做出相应的行为
- 获取鼠标位置
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Name="rect" Fill="LightBlue" MouseMove="rect_MouseMove"></Rectangle>
<Button Grid.Row="1" Name="cmdCapture" Click="cmdCapture_Click">Caputure the Mouse</Button>
<TextBlock Name="lblInfo" Grid.Row="2"></TextBlock>
</Grid>
private void rect_MouseMove(object sender, MouseEventArgs e)
{
Point point = e.GetPosition(this);
this.lblInfo.Text = $"You are at ({point.X},{point.Y}) in window coordinate";
}
private void cmdCapture_Click(object sender, RoutedEventArgs e)
{
Mouse.Capture(this.rect);
this.cmdCapture.Content = $"Mouse id now captured...";
}
- 拖动文本
- 输入框自带拖动
- Label控件需要添加
AllowDrop="true"
才可以被拖动的内容覆盖 MouseDown="lblSource_MouseDown"
事件将控件内容添加到拖动库中Drop="lblTarget_Drop"
事件将控件的内容设置为拖动库中的内容
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Padding="10" VerticalAlignment="Center" HorizontalAlignment="Center">Drag from this TextBox</TextBox>
<Label Grid.Column="1" Padding="20" Background="LightGoldenrodYellow" Name="lblSource" VerticalAlignment="Center" HorizontalAlignment="Center" MouseDown="lblSource_MouseDown">Orginal Label</Label>
<Label Grid.Row="1" Grid.ColumnSpan="2" Background="LightGoldenrodYellow" VerticalAlignment="Center" HorizontalAlignment="Right" Padding="20" Name="lblTarget" AllowDrop="True" Drop="lblTarget_Drop">Target Label</Label>
<TextBox Grid.Row="2" Grid.Column="0" Height="30"></TextBox>
</Grid>
private void lblSource_MouseDown(object sender, MouseButtonEventArgs e)
{
Label label = (Label)sender;
DragDrop.DoDragDrop(label, label.Content, DragDropEffects.Copy);
}
private void lblTarget_Drop(object sender, DragEventArgs e)
{
((Label)sender).Content = e.Data.GetData(DataFormats.Text);
}
控件类
- 设置文本
TextDecorations="Strikethrough"
:为文本添加删除线TextOptions.TextFormattingMode="Display"
:能够使小字号(小于15)的文本显示的更清晰
<Grid>
<StackPanel Margin="5" >
<Button x:Name="button" Content="按钮" Background="Blue" Foreground="Red" FontFamily="宋体,Times New Roman" FontSize="16" FontStyle="Italic" FontWeight="Bold" FontStretch="Normal" Cursor="Help"/>
<ListBox x:Name="listBox" Height="56" RenderTransformOrigin="0.5,0.5" Margin="-1,0,1,0">
<ListBox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleX="0.262"/>
<RotateTransform/>
<TranslateTransform X="0.651"/>
</TransformGroup>
</ListBox.RenderTransform>
<TextBlock x:Name="textBlock" TextWrapping="Wrap" RenderTransformOrigin="0.67,5.532"/>
</ListBox>
<TextBlock x:Name="textBlock1" TextWrapping="Wrap" Text="TextBlock: My test is here,ideal text is blurry at small sizes" TextDecorations="Strikethrough" FontSize="12"/>
<TextBlock x:Name="textBlock2" TextOptions.TextFormattingMode="Display" TextWrapping="Wrap" Text="TextBlock:Display text is crisp" FontSize="12"/>
</StackPanel>
</Grid>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//设置按钮背景色
//this.button.Background = new SolidColorBrush(Colors.Red);
//this.button.Background = new SolidColorBrush(Color.FromRgb(255,0,0));
//设置按钮中字的颜色
//this.button.Foreground = SystemColors.ControlDarkBrush;
//设置光标类型
this.Cursor = Cursors.Wait;
//显示出所有的字体
foreach (FontFamily fontFamily in Fonts.SystemFontFamilies)
this.listBox.Items.Add(fontFamily.Source);
}
内容控件
- 键盘事件
IsCancel="True"
:按ESC键可以启动该控件点击事件IsDefault="True"
:按Enter键可以启动该控件点击事件
- 提示功能ToolTip
ToolTip="退出"
:提示功能Background="#60AA4030"
:设置提示的背景颜色,60表示透明度(0~100)Placement="Absolute" HorizontalOffset="100" VerticalOffset="10"
:设置提示的位置在绝对位置,水平距离屏幕左端100px,垂直距离屏幕上端10px
- 单选按钮RadioButton
- GroupName=”rdo”:不在同一控件下的RadioButton是不互斥的,为了起到互斥的作用,需要添加此属性,表示她们是一组的
- 复选框按钮CheckBox
IsChecked="True"
:表示该项默认选中IsChecked="{x:Null}"
:表示该项不确定IsThreeState="True"
:表示该项有三种状态:未选中、不确定、选中
<Grid>
<StackPanel RenderTransformOrigin="0.482,0.509" >
<Button x:Name="button" HorizontalContentAlignment="Left" IsCancel="True" IsDefault="True" Click="button_Click" ToolTip="退出">Button</Button><!--isCancel=true:按esc建可启动 | isDefault:enter键触发-->
<Button x:Name="button1" Height="50">
<Button.ToolTip>
<ToolTip Background="#60AA4030" Placement="Absolute" HorizontalOffset="100" VerticalOffset="10"><!--60是透明度-->
<StackPanel>
<TextBlock>Image and text</TextBlock>
<Image Source="C:\Users\Administrator\Pictures\2.jpg"></Image>
</StackPanel>
</ToolTip>
</Button.ToolTip>
<Image Source="C:\Users\Administrator\Pictures\2.jpg"></Image>
</Button>
<Button x:Name="button2">
<StackPanel>
<TextBlock>Image and text button</TextBlock>
<Image Source="C:\Users\Administrator\Pictures\eyes.png" Stretch="None"></Image>
<TextBlock>Courtesy of the StackPanel</TextBlock>
<RadioButton x:Name="radioButton1" Content="RadioButton1" GroupName="rdo"/><!--加了GroupName不同容器的radio就可以互斥了-->
</StackPanel>
</Button>
<!--通过设置Target="{Binding ElementName=textBox}"来表名该Label是哪一个输入框的标签
Choose _A中的“_A”表示可以通过Alt + A来快速定位到该Label所指的输入框中-->
<Label x:Name="label" Target="{Binding ElementName=textBox}">Choose _A</Label><!--alt + a-->
<TextBox x:Name="textBox" Height="23" TextWrapping="Wrap" Text="TextBox"/>
<CheckBox x:Name="checkBox" Content="CheckBox" IsChecked="True" IsThreeState="True"/>
<CheckBox x:Name="checkBox1" Content="CheckBox1" IsChecked="{x:Null}"/>
<RadioButton x:Name="radioButton" Content="RadioButton" IsChecked="True" GroupName="rdo"/><!--必须在同一容器下才能互斥-->
</StackPanel>
</Grid>
private void button_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
Popup
- Popup属性
StaysOpen="False"
:设置是否保持打开Placement="Mouse"
:设置显示位置在鼠标的位置PopupAnimation="Slide"
:设置动画为滑动AllowsTransparency="True"
:是否允许透明
- 边框Border属性
BorderBrush="Beige"
:设置画刷为米色BorderThickness="2"
:设置边框粗细为2px
- 超链接
- <
Hyperlink NavigateUri
=”http://www.hao123.com” Click=”Hyperlink_Click”>wikipedia</Hyperlink
> Process.Start(((Hyperlink)sender).NavigateUri.ToString());
:转到超链接所指向的网址
- <
<Grid>
<TextBlock TextWrapping="Wrap">You can use a Popup to provide a link for a sepecific <Run TextDecorations="Underline" MouseEnter="Run_MouseEnter">term</Run> of interest</TextBlock>
<Popup Name="popLink" StaysOpen="False" Placement="Mouse" MaxWidth="200" PopupAnimation="Slide" AllowsTransparency="True">
<Border BorderBrush="Beige" BorderThickness="2" Background="White">
<TextBlock Margin="10" TextWrapping="Wrap">
For more information,see
<Hyperlink NavigateUri="http://www.hao123.com" Click="Hyperlink_Click">wikipedia</Hyperlink>
</TextBlock>
</Border>
</Popup>
</Grid>
private void Run_MouseEnter(object sender, MouseEventArgs e)
{
popLink.IsOpen = true;
}
private void Hyperlink_Click(object sender, RoutedEventArgs e)
{
Process.Start(((Hyperlink)sender).NavigateUri.ToString());
}
特殊容器控件:ScrollViewer
VerticalScrollBarVisibility="Auto"
:设置垂直滚动条显示方式
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Click="Button_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="81">Up</Button>
<ScrollViewer Name="scrollViewer" Grid.Row="1" Margin="3" VerticalScrollBarVisibility="Auto">
<TextBox TextWrapping="Wrap">
这里是一些文本
</TextBox>
</ScrollViewer>
<Button Name="button1" Grid.Row="0" VerticalAlignment="Top" Height="30" Width="81" Content="to end" Click="button1_Click"/>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
//this.scrollViewer.LineUp();
this.scrollViewer.PageUp();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.scrollViewer.ScrollToEnd();
}
CanContentScroll="True"
:设置滚动时按照元素进行滚动
<ScrollViewer Name="scrollViewer" CanContentScroll="True"><!--一次滚动一个元素-->
<StackPanel>
<Button x:Name="button" Content="Button" Width="75" Height="150"/>
<Button x:Name="button1" Content="Button1" Width="75" Height="150"/>
<Button x:Name="button2" Content="Button2" Width="75" Height="150"/>
<Button x:Name="button3" Content="Button3" Width="75" Height="150"/>
</StackPanel>
</ScrollViewer>
带标题的内容控件:GroupBox
<Grid>
<GroupBox x:Name="groupBox" Header="我是标题" Margin="5">
<StackPanel>
<RadioButton Name="radioButton">first</RadioButton>
<RadioButton Name="radioButton1">second</RadioButton>
<RadioButton Name="radioButton2">third</RadioButton>
<Button>确定</Button>
</StackPanel>
</GroupBox>
</Grid>
带标题的内容控件:TabItem
TabStripPlacement="Top"
:设置选项卡位置在顶部
<Grid>
<TabControl x:Name="tabControl" Margin="5" TabStripPlacement="Top">
<TabItem>
<!--这是选项卡标题-->
<TabItem.Header>
<StackPanel>
<TextBlock Margin="3">Image and Text</TextBlock>
<Image Source="C:\Users\Administrator\Pictures\eyes.png" Stretch="None"></Image>
<TextBox>:</TextBox>
</StackPanel>
</TabItem.Header>
<!--这是选项卡内容-->
<StackPanel>
<CheckBox>One</CheckBox>
<CheckBox>Two</CheckBox>
<CheckBox>Three</CheckBox>
<Button Click="Button_Click">确定</Button>
</StackPanel>
</TabItem>
<TabItem Header="TabItem" Name="tabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
this.tabItem.IsSelected = true;
}
带标题的内容控件:Expander
ExpandDirection="Up"
:设置扩展项弹出方向为向上
<StackPanel>
<Expander x:Name="expander" Header="Expander" Margin="5" ExpandDirection="Up">
<Button Height="50" Width="50">first</Button>
</Expander>
<Expander x:Name="expander1" Header="Expander" Margin="5">
<ScrollViewer Height="200">
<TextBlock TextWrapping="Wrap">这里是一些文本</TextBlock>
</ScrollViewer>
</Expander>
</StackPanel>
文本控件:TextBox、PasswordBox
SelectionChanged="TextBox_SelectionChanged"
:设置选择文本改变时事件PasswordChar="*"
:设置输入密码时显示的字符
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox Name="textBox" SpellCheck.IsEnabled="True" Grid.Row="0" MaxLength="10" Margin="5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" SelectionChanged="TextBox_SelectionChanged">
这里是一些文本
</TextBox>
<ScrollViewer Foreground="Blue" Grid.Row="1" Margin="0,10,0,5" VerticalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock>Current Selection</TextBlock>
<TextBlock Name="txtSelection" TextWrapping="Wrap"></TextBlock>
</StackPanel>
</ScrollViewer>
<PasswordBox Grid.Row="2" PasswordChar="*"></PasswordBox>
</Grid>
private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
if (this.txtSelection == null)
return;
this.txtSelection.Text = $"Selection from {this.textBox.SelectionStart} to len {this.textBox.SelectionLength} is {this.textBox.SelectedText}";
}
列表控件 ListBox、ComboBox
- SelectedIndex=”0”:ComboBox默认选中第一项
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ListBox Margin="5" Height="Auto" VerticalAlignment="Top" Grid.Row="0">
<ListBoxItem>
<Image Source="C:\Users\Administrator\Pictures\eyes.png"></Image>
</ListBoxItem>
<ListBoxItem>Red</ListBoxItem>
<ListBoxItem>Blue</ListBoxItem>
<ListBoxItem>Black</ListBoxItem>
<StackPanel Orientation="Horizontal">
<Image Source="C:\Users\Administrator\Pictures\eyes.png"></Image>
<Label VerticalContentAlignment="Center">eyes</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="C:\Users\Administrator\Pictures\2.jpg" Height="20"></Image>
<Label>Drogon Ball</Label>
</StackPanel>
</ListBox>
<ListBox Grid.Row="1" Name="list" SelectionChanged="list_SelectionChanged">
<CheckBox>One</CheckBox>
<CheckBox>Two</CheckBox>
<CheckBox>Three</CheckBox>
</ListBox>
<StackPanel Grid.Row="2">
<TextBlock>Current Selection</TextBlock>
<TextBlock Name="txtSelction" TextWrapping="Wrap"></TextBlock>
<Button Click="Button_Click">Examine All Items</Button>
</StackPanel>
<ComboBox Grid.Row="3" Height="20" SelectedIndex="0">
<ComboBoxItem>A</ComboBoxItem>
<ComboBoxItem>B</ComboBoxItem>
</ComboBox>
</Grid>
private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (list.SelectedItem == null)
return;
this.txtSelction.Text = $"You choose item at position {list.SelectedIndex + 1}\r]nChecked state is {((CheckBox)list.SelectedItem).IsChecked}";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
StringBuilder str = new StringBuilder();
foreach(CheckBox item in list.Items)
{
if(item.IsChecked == true)
{
str.Append($"{item.Content} is checked\r\n");
}
txtSelction.Text = str.ToString();
}
}
基于范围的控件:Slider、ProgressBar
- 滑动条
Orientation
:设置方向是水平的还是垂直的Maximum、Minimum、Value
:设置最大值、最小值和当前值TickPlacement="BottomRight"
:设置刻度在右下角TickFrequency="5"
:设置刻度的频率是5Ticks="10,30,70"
:设置只显示指定位置的刻度IsSelectionRangeEnabled="True"
:设置是否显示选择范围SelectionStart="70" SelectionEnd="100"
:设置范围开始位置和结束位置SmallChange="1" LargeChange="10"
:设置小变化和大变化规格
- 进度条
IsIndeterminate="True"
:设置进度条为不确定状态
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Slider Grid.Row="0" x:Name="slider" Orientation="Horizontal" Maximum="100" Minimum="0" Value="50" TickPlacement="BottomRight" TickFrequency="5" Ticks="10,30,70" IsSelectionRangeEnabled="True" SelectionStart="70" SelectionEnd="100" SmallChange="1" LargeChange="10" Margin="5" VerticalAlignment="Top"/>
<ProgressBar Name="progressBar" Grid.Row="1" Height="10" Maximum="100" Minimum="0" Value="50" Margin="5" VerticalAlignment="Center"/>
<ProgressBar Grid.Row="1" IsIndeterminate="True" VerticalAlignment="Top" Height="20"/>
<Button x:Name="button" Content="流动" Grid.Row="1" Height="30" VerticalAlignment="Bottom" Click="button_Click"/>
</Grid>
日期控件:Calendar、DatePicker
- 日历Calendar
DisplayMode
:设置显示的类别IsTodayHighlighted="True"
:设置今日是否高亮SelectionMode="MultipleRange"
:设置选择方式是多选DisplayDateStart="2016-11-11"
:设置开始日期FirstDayOfWeek="Monday"
:设置自然周的第一天SelectedDate="2016-11-15"
:设置选中的日期SelectedDatesChanged="Calendar_SelectedDatesChanged"
:选中的日期变化时事件
- 日期选择器DatePicker
IsDropDownOpen="False"
:设置是否展开DateValidationError="DatePicker_DateValidationError"
:日期无效时事件
<Grid>
<Calendar DisplayMode="Year" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<Calendar DisplayMode="Decade" HorizontalAlignment="Left" Margin="194,10,0,0" VerticalAlignment="Top"/>
<Calendar Name="calendar" IsTodayHighlighted="True" SelectionMode="MultipleRange" DisplayMode="Month" DisplayDateStart="2016-11-11" FirstDayOfWeek="Monday" SelectedDate="2016-11-15" HorizontalAlignment="Left" Margin="373,10,-35,0" VerticalAlignment="Top" SelectedDatesChanged="Calendar_SelectedDatesChanged"/>
<Button Name="button" VerticalAlignment="Bottom" Click="button_Click">确定</Button>
<DatePicker IsDropDownOpen="False" HorizontalAlignment="Left" Margin="10,202,0,0" VerticalAlignment="Top" DateValidationError="DatePicker_DateValidationError"/>
</Grid>
private void button_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < this.calendar.SelectedDates.Count; i++)
s += this.calendar.SelectedDates[i].ToShortDateString() + ";";
this.Title = s;
}
private void DatePicker_DateValidationError(object sender, DatePickerDateValidationErrorEventArgs e)
{
MessageBox.Show($"非法日期!\n{e.Exception.Message}");
}
绑定
IsSnapToTickEnabled="True"
:只允许值为整数FontSize="{Binding ElementName=slider,Path=Value,Mode=TwoWay}"
:将FontSize的值绑定到Name为slider
的Value
属性上,并且方式为双向绑定
Foreground="{Binding ElementName=listBox,Path=SelectedItem.Tag}"
:将Foreground的值绑定到Name为listBox
的被选中的项目的Tag
属性上,默认单向绑定
UpdateSourceTrigger=PropertyChanged
:属性值改变时立即更新
<Grid>
<StackPanel Margin="5" >
<Slider x:Name="slider" Height="Auto" Margin="3" Minimum="1" Maximum="40" TickFrequency="1" Value="12" TickPlacement="BottomRight" LargeChange="10" SmallChange="1" IsSnapToTickEnabled="True"/>
<TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="Simple Text" Margin="10" Height="Auto" FontSize="{Binding ElementName=slider,Path=Value,Mode=TwoWay}" Foreground="{Binding ElementName=listBox,Path=SelectedItem.Tag}"/>
<TextBlock x:Name="textBlock1" TextWrapping="Wrap" Text="Code Binding Test" Margin="10"/>
<Button x:Name="button" Content="Button" Click="button_Click"/>
<Button x:Name="button1" Content="删除绑定" Margin="0,10,0,0" Click="button1_Click"/>
<ListBox x:Name="listBox" Height="Auto" Margin="5">
<ListBoxItem Tag="Blue">Blue</ListBoxItem>
<ListBoxItem Tag="DarkBlue">Dark Blue</ListBoxItem>
<ListBoxItem Tag="Red">Red</ListBoxItem>
</ListBox>
<TextBox x:Name="textBox" Height="23" TextWrapping="Wrap" Margin="3" Text="{Binding ElementName=textBlock,Path=FontSize,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
private void button_Click(object sender, RoutedEventArgs e)
{
//this.slider.Value = 30;
this.textBlock.FontSize = 30;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//推荐在XAML中设置
//不推荐在代码中绑定
Binding binding = new Binding();
binding.Source = slider;
binding.Path = new PropertyPath("Value");
binding.Mode = BindingMode.TwoWay;
this.textBlock1.SetBinding(TextBlock.FontSizeProperty,binding);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
BindingOperations.ClearAllBindings(this.textBlock);
BindingOperations.ClearAllBindings(this.textBlock1);
}
绑定到非元素对象:Source、RelativeSource、DataContext
- Source
Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"
:将Text绑定到系统字体中的图标字体家族Text="{Binding Source={StaticResource CustomFont},Path=Source}"
:将Text绑定到自己建立的静态资源Key="CustomFont"
上
- RelativeSource
Mode="FindAncestor"
:绑定模式设置为绑定到父元素AncestorType="{x:Type StackPanel}"
:过滤父元素的类型Text="{Binding Path=Name,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}, AncestorLevel=2}}"
:将Text绑定到StackPanel
父元素的Name
属性上,AncestorLevel
表示第二层的父元素
- DataContext
DataContext="{x:Static SystemFonts.IconFontFamily}"
:在父元素将DataContext绑定到一个静态资源Text="{Binding Path=Source}"
:然后直接使用DataContext绑定的资源
<Window.Resources><!--资源-->
<FontFamily x:Key="CustomFont">Calibri</FontFamily>
</Window.Resources>
<Grid>
<StackPanel Name="statckPanelOut">
<StackPanel Margin="3" Name="stackPanel" DataContext="{x:Static SystemFonts.IconFontFamily}">
<!--Source-->
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource CustomFont},Path=Source}"></TextBlock>
<!--RelativeSource-->
<TextBlock Margin="0,50,0,0">
<TextBlock.Text>
<Binding Path="Name"><!--对应于StackPanel的Name-->
<!--<Binding Path="Margin">-->
<Binding.RelativeSource>
<RelativeSource Mode="FindAncestor" AncestorType="{x:Type StackPanel}"></RelativeSource>
<!--<RelativeSource Mode="Self" ></RelativeSource>-->
</Binding.RelativeSource>
</Binding>
</TextBlock.Text>
</TextBlock>
<TextBlock Margin="0,10,0,0" Text="{Binding Path=Title,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"></TextBlock>
<TextBlock Name="textBlock1" Margin="5" Text="{Binding Path=Name,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}}}"></TextBlock>
<TextBlock Name="textBlock" Margin="5" Text="{Binding Path=Name,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}, AncestorLevel=2}}"></TextBlock>
<!--DataContext-->
<TextBlock Margin="0,50,0,0" Text="{Binding Path=Source}"></TextBlock>
<TextBlock Margin="0,5,0,0" Text="{Binding Path=LineSpacing}"></TextBlock>
<TextBlock Margin="0,5,0,0" Text="{Binding Path=FamilyTypefaces[0].Style}"></TextBlock>
</StackPanel>
</StackPanel>
</Grid>
资源基础
x:Key="TileBrush"
:索引名为TileBrushTileMode="Tile"
:平铺模式为平铺ViewportUnits="Absolute"
:绝对大小Viewport="0 0 32 32"
:x,y,长度,高度
<Window.Resources>
<ImageBrush x:Key="TileBrush" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 32 32" ImageSource="C:\Users\Administrator\Pictures\2.jpg"></ImageBrush>
</Window.Resources>
<StackPanel Name="stackPanel" Margin="5">
<StackPanel.Resources>
<ImageBrush x:Key="TileBrush1" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 32 32" ImageSource="C:\Users\Administrator\Pictures\2.jpg"></ImageBrush>
</StackPanel.Resources>
<Button Content="平铺的按钮" Background="{StaticResource TileBrush}" Margin="3" Name="button" FontSize="14" Padding="5"></Button>
<Button Content="Second_2" Margin="3" Name="button1" FontSize="14" Padding="5">
<Button.Resources>
<ImageBrush x:Key="TileBrush1" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 20 20" ImageSource="C:\Users\Administrator\Pictures\3.jpg"></ImageBrush>
</Button.Resources>
<Button.Background>
<StaticResource ResourceKey="TileBrush1"></StaticResource>
</Button.Background>
</Button>
<Button Content="Third_3" Background="{DynamicResource TileBrush1}" Margin="3" Name="button2" FontSize="14" Padding="5"></Button>
<Button Content="Use a Static Resource" Background="{StaticResource TileBrush1}" Margin="0,50,0,0" Name="buttonStatic" Padding="5"/>
<Button Content="Change the Brush" Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" Name="buttonChange" Padding="5" Click="buttonChange_Click"/><!--动态资源-->
<Button Content="Use a Dynamic Resource" Background="{DynamicResource TileBrush1}" Name="buttonDynamic" Padding="5"/>
</StackPanel>
样式基础
- Style属性
TargetType="Button"
:设置该样式赋给全部的buttonBasedOn="{StaticResource BigFontButtonStyle}"
:设置该样式继承自键值为BigFontButtonStyle的样式
Style="{x:Null}"
:设置样式为无- ImageBrush
TileMode="Tile"
:设置平铺样式为平铺ViewportUnits="Absolute"
:设置视窗为绝对位置Viewport="0 0 32 32"
:设置视窗从0,0位置开始,宽32 高32
<Window.Resources>
<Style x:Key="BigFontButtonStyle"><!--该样式的键值-->
<Setter Property="Control.FontFamily" Value="Times New Roman"></Setter><!--设置字体为新罗马字体-->
<Setter Property="Button.FontSize" Value="18"></Setter><!--设置字体大小-->
<!--<Setter Property="TextBlock.FontSize" Value="10"></Setter> 不管属性是什么,同类型的选择最后一个-->
<Setter Property="Control.FontWeight" Value="Bold"></Setter><!--设置粗体-->
<Setter Property="Control.Background"><!--设置背景-->
<Setter.Value>
<ImageBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 32 32" Opacity="0.3" ImageSource="2.jpg"></ImageBrush><!--设置背景为图片-->
</Setter.Value>
</Setter>
</Style>
<!--<Style TargetType="Button" BasedOn="{StaticResource BigFontButtonStyle}"> 自动为所有按钮设置上面的样式,如果按钮不想设置,则添加Style="{x:Null}"-->
<Style x:Key="EmphasizedBigFontButtonStyle" BasedOn="{StaticResource BigFontButtonStyle}">
<Setter Property="Control.Foreground" Value="White"></Setter>
<Setter Property="Control.Background" Value="DarkBlue"></Setter>
<Setter Property="Button.FontSize" Value="10"></Setter>
</Style>
</Window.Resources>
<Window.Resources>
<Style x:Key="MouseOverHighlight">
<Setter Property="TextBlock.Padding" Value="5"></Setter>
<EventSetter Event="FrameworkElement.MouseEnter" Handler="Element_MouseEnter"></EventSetter><!--当鼠标进入时发生Element_MouseEnter事件-->
<EventSetter Event="FrameworkElement.MouseLeave" Handler="Element_MouseLeave"></EventSetter>
</Style>
</Window.Resources>
private void Element_MouseEnter(object sender,MouseEventArgs e)
{
((TextBlock)sender).Background = new SolidColorBrush(Colors.Red);
}
private void Element_MouseLeave(object sender,MouseEventArgs e)
{
((TextBlock)sender).Background = null;
}
触发器
简单触发器–单条件触发器
<!--是有顺序的,应用最后的触发器-->
<Style.Triggers>
<!--当控件获得焦点时,前景色变成白色-->
<Trigger Property="Control.IsFocused" Value="True">
<Setter Property="Control.Foreground" Value="White" />
</Trigger>
<!--当按钮被按下时,前景色变成红色-->
<Trigger Property="Button.IsPressed" Value="True">
<Setter Property="Control.Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
简单触发器–多条件触发器
<!--有多个条件的触发器-->
<!--当控件获得焦点并且鼠标悬停的时候前景色变成蓝色-->
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Control.IsFocused" Value="True"></Condition>
<Condition Property="Control.IsMouseOver" Value="True"></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Control.Foreground" Value="Blue"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
事件触发器
RoutedEvent="Mouse.MouseEnter"
:路由事件为鼠标进入Storyboard.TargetName="A"
:为目标名为A的控件设置触发器Storyboard.TargetProperty="FontSize"
:为目标的FontSize属性设置触发器From="10"
:从属性值10开始To = "50"
:到属性值50结束Duration="0:0:0.2"
:用时为0小时0分0.2秒
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!--0小时0分0.2秒-->
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="FontSize" To="48"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<!--反转触发器-->
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!--0小时0分1秒-->
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="FontSize"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
形状
Stroke="Red"
:设置边沿色为红色StrokeThickness="15"
:设置边沿粗细Fill="Blue"
:设置填充色为蓝色RadiusX="10"
:设置x轴的长度为10,以便成弧RadiusY="50"
:设置y轴的长度为50,以便成弧Stretch="Uniform"
:按比例改变容器的高度和宽度,直到接触边缘Stretch="UniformToFill"
:按比例改变容器的高度和宽度,直到占满整个可用空间Stretch="Fill"
:自动适应空间大小
<StackPanel>
<Rectangle Stroke="Red" Fill="Blue" RadiusX="10" RadiusY="50" Height="84" HorizontalAlignment="Center" Width="344"/>
<Ellipse Fill="Yellow" Stroke="Blue" Grid.Row="1" Stretch="Fill"></Ellipse>
</StackPanel>
- Viewbox:能够使形状按比例缩放
- 直线 Line
X1="0" Y1="0" X2="10" Y2="100"
:设置直线起点为0,0 终点为10,100StrokeStartLineCap="Triangle" StrokeEndLineCap="Round"
:设置直线起点帽为三角形,终点帽为弧形
- 折线 Polyline
StrokeDashArray="1 2" StrokeThickness="5"
:设置此属性后折线将变为实心为5个单位,空心为10个单位Points="5,5 10,10 15,10 25,20"
:设置折线的各点
- 折线 Polygon
- 后面的图形会覆盖前面的图形
<Viewbox Grid.Row="1" HorizontalAlignment="Left"><!--使形状按比例缩放-->
<Canvas Width="200" Height="150">
<Line Stroke="Red" StrokeThickness="15" StrokeStartLineCap="Triangle" StrokeEndLineCap="Round" X1="0" Y1="0" X2="10" Y2="100" Canvas.Left="150" />
<Polyline Stroke="Blue" StrokeDashArray="1 2" StrokeThickness="2" Points="5,5 10,10 15,10 25,20" />
<!--折线 StrokeDashArray="1 2" StrokeThickness="5":实心为5个单位,空心为10个单位-->
<Polygon Stroke="Blue" Fill="Aqua" Points="5,5 10,10 15,10 25,50" Canvas.Left="100" /><!--多边形-->
<Ellipse Fill="Black" Stroke="Red" Canvas.Left="10" Canvas.Top="50" Width="100" Height="50" HorizontalAlignment="Left" />
<Rectangle Fill="Yellow" Stroke="Red" Canvas.Left="30" Canvas.Top="40" Width="100" Height="70" HorizontalAlignment="Left" />
</Canvas>
</Viewbox>
画刷
- 图片画刷 ImageBrush
TileMode="Tile" ViewportUnits="RelativeToBoundingBox" Viewport="0,0 0.5,0.5"
:按比例进行平铺 ,从0,0开始到0.5,0.5第一副图结束,然后平铺TileMode="Tile" ViewportUnits="Absolute" Viewport="0,0 50,50"
:按绝对进行平铺,开始位置是0,0 大小是50*50Viewbox="0,0,1,1"
:截取图像
<!-- TileMode="Tile" ViewportUnits="RelativeToBoundingBox":按比例进行平铺 Viewport="0,0 0.5,0.5":从0,0开始到0.5,0.5第一副图结束,然后平铺-->
<ImageBrush ImageSource="head.jpg" Stretch="Uniform" TileMode="Tile" ViewportUnits="RelativeToBoundingBox" Viewport="0,0 0.5,0.5"></ImageBrush>
<!--TileMode="Tile" ViewportUnits="Absolute" Viewport="0,0 50,50":按绝对进行平铺,开始位置是0,0 大小是50*50-->
<ImageBrush ImageSource="head.jpg" Stretch="Uniform" TileMode="Tile" ViewportUnits="Absolute" Viewport="0,0 50,50"></ImageBrush>
- 固体画刷 SolidColorBrush
<Button Name="button" Width="100" Height="50" Content="button">
<Button.Background>
<SolidColorBrush Color="LightBlue" />
</Button.Background>
</Button>
- 渐变画刷 LinearGradientBrush
StartPoint="0,0" EndPoint="0,1"
:设置渐变开始点为0,0 结束点为0,1 默认是从0,0到1,1Offset
:范围0~1,设置各种渐变色的开始位置
<Rectangle Width="150" Height="100" Margin="5">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"><!--渐变画刷,左上角坐标是00,右下角坐标是11,默认从00到11渐变-->
<GradientStop Color="Blue" Offset="0"></GradientStop><!--Offset="0"表示以蓝色开头,它的值在0到1之间-->
<GradientStop Color="Red" Offset="0.3"></GradientStop>
<GradientStop Color="White" Offset="1"></GradientStop>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Margin="5" Text="这个文本使用了渐变色">
<TextBlock.Foreground>
<LinearGradientBrush>
<GradientStop Color="Blue" Offset="0"></GradientStop>
<GradientStop Color="Red" Offset="0.3"></GradientStop>
<GradientStop Color="White" Offset="1"></GradientStop>
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
- 径向渐变画刷 RadialGradientBrush
GradientOrigin="0.5,0.5"
:从该点向外扩散(默认的)RadiusX="1" RadiusY="1"
:渐变沿xy轴的长度,范围0~1
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.5,0.5" RadiusX="1" RadiusY="1"><!--GradientOrigin="0.5,0.5":从该点向外扩散(默认的)-->
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="White" Offset="1" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
- 视觉画刷 VisualBrush————位图画刷 BitmapCacheBrush
把button的外观复制到矩形上
<Button Name="button" Content="是真的按钮吗?"></Button>
<Rectangle Margin="5" Name="rectangle" Stroke="Black" Height="100">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=button}" />
<!--<BitmapCacheBrush Target="{Binding ElementName=button}" BitmapCache="BitmapCache" /> 有问题-->
</Rectangle.Fill>
</Rectangle>
变换与透明
- RotateTransform 旋转
<Canvas>
<!--变换形状-->
<!--方式 1-->
<Rectangle Width="80" Height="10" Stroke="Red" Fill="Yellow" Canvas.Left="100" Canvas.Top="100"></Rectangle>
<Rectangle Width="80" Height="10" Stroke="Red" Fill="Yellow" Canvas.Left="100" Canvas.Top="100">
<Rectangle.RenderTransform><!--Angle="25":以旋转点顺时针旋转25度,CenterX="40" CenterY="5":设置旋转点-->
<RotateTransform Angle="25" CenterX="40" CenterY="5" />
</Rectangle.RenderTransform>
</Rectangle>
<!--方式 2-->
<Rectangle Width="80" Height="10" Stroke="Red" Fill="Beige" Canvas.Left="100" Canvas.Top="100" RenderTransformOrigin="0.5,0.5"><!--RenderTransformOrigin="0.5,0.5":设置旋转中心点为中间-->
<Rectangle.RenderTransform>
<RotateTransform Angle="50"/>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
- ScaleTransform 缩放
<Grid Margin="5" Grid.IsSharedSizeScope="True" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" SharedSizeGroup="Row"></RowDefinition>
<RowDefinition SharedSizeGroup="Row"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Name="textbox" FontSize="30">这里有一些反射文本</TextBox>
<Rectangle Grid.Row="1" RenderTransformOrigin="1,0.5">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=textbox}"></VisualBrush>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Transparent" Offset="0.3" />
<GradientStop Color="#44000000" Offset="1" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.RenderTransform>
<ScaleTransform ScaleY="-1"></ScaleTransform>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
- RenderTransform和LayoutTransform
RenderTransform
:可以超过边界,先布局,再转换LayoutTransform
:不超过边界,选转换,再布局
<StackPanel>
<!--RenderTransform:可以超过边界,先布局,再转换-->
<StackPanel Margin="25" Background="LightYellow">
<!--旋转元素-->
<Button Padding="5" HorizontalAlignment="Left">
<Button.RenderTransform>
<RotateTransform Angle="35" CenterX="45" CenterY="5" />
</Button.RenderTransform>
<Button.Content>旋转元素</Button.Content>
</Button>
<Button Padding="5" HorizontalAlignment="Left" Content="无旋转"></Button>
</StackPanel>
<!--LayoutTransform:不超过边界,选转换,再布局-->
<StackPanel Margin="25" Background="#A0FF0000">
<!--A0是α值,范围是从00到ff,设置透明度-->
<!--<StackPanel.Background>
<ImageBrush ImageSource="head.jpg" Opacity="0.7"></ImageBrush>
</StackPanel.Background>-->
<!--旋转元素-->
<Button Padding="5" HorizontalAlignment="Left" Opacity="0.5">
<Button.LayoutTransform>
<RotateTransform Angle="35" CenterX="45" CenterY="5" />
</Button.LayoutTransform>
<Button.Content>旋转元素</Button.Content>
</Button>
<Button Padding="5" HorizontalAlignment="Left" Content="无旋转"></Button>
</StackPanel>
</StackPanel>
- OpacityMask 透明掩码
<Window.Background>
<ImageBrush ImageSource="head.jpg" />
</Window.Background>
<Grid Margin="5">
<!--透明掩码-->
<Button Background="Purple" FontSize="14" FontWeight="Bold" Height="100">
<Button.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Transparent" Offset="1" /><!-- Color="Transparent":设置为透明色-->
</LinearGradientBrush>
</Button.OpacityMask>
<Button.Content>一个部分透明的按钮</Button.Content>
</Button>
</Grid>
路径和几何图形
FillRule
:EvenOdd-交叉处透明(默认),Nonzero-交叉处不变Rect="0,0 100,50"
:设置图形左上角坐标为0,0 右下角为100,50
<Window.Resources>
<GeometryGroup x:Key="Geometry" FillRule="EvenOdd"><!-- FillRule="Nonzero":交叉处不变化-->
<!--图形交叉处默认为空白色,是透明的-->
<EllipseGeometry Center="200,50" RadiusX="50" RadiusY="25"></EllipseGeometry>
<RectangleGeometry Rect="150,25 100,50" ></RectangleGeometry>
</GeometryGroup>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Fill="Yellow" Stroke="Blue" Width="100" Height="50"></Rectangle>
<!--<Path Fill="Yellow" Stroke="Blue" Grid.Row="1">
<Path.Data>
--><!--<RectangleGeometry Rect="0,0 100,50" />--><!--Rect="0,0 100,50":设置图形左上角坐标为0,0 右下角为100,50-->
<!--<LineGeometry StartPoint="0,0" EndPoint="100,50" />--><!--
</Path.Data>
</Path>-->
<Path Fill="Yellow" Stroke="Blue" Grid.Row="1" Data="{StaticResource Geometry}"></Path>
<Path Grid.Row="2" Fill="Red" Stroke="Green" Data="{StaticResource Geometry}"></Path>
</Grid>
拼接图形
GeometryCombineMode
:
Intersect
:取相交的Union
:都取Xor
:相交处透明Exclude
:排除第二个图形
<Window.Resources>
<CombinedGeometry x:Key="Geometry" GeometryCombineMode="Union"><!--GeometryCombineMode:Intersect取相交的 Union都取 Xor相交处透明 Exclude排除第二个图形-->
<CombinedGeometry.Geometry1>
<EllipseGeometry Center="200,50" RadiusX="50" RadiusY="25"></EllipseGeometry>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="100,5 100,50" ></RectangleGeometry>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Path Fill="Yellow" Stroke="Blue" Grid.Row="0" Data="{StaticResource Geometry}"></Path>
<Path Stroke="Blue" Grid.Row="1">
<Path.Data>
<!--<PathGeometry>--><!--折线和多边形--><!--
<PathFigure StartPoint="0,0" IsClosed="True">--><!--IsClosed="True":闭合-->
<!--<LineSegment Point="100,100" />
<LineSegment Point="200,100" />
<LineSegment Point="100,0" />
</PathFigure>
</PathGeometry>-->
<PathGeometry>
<!--曲线-->
<PathFigure StartPoint="0,0" IsClosed="False">
<!--<ArcSegment Point="100,100" Size="100,200" IsLargeArc="False" />--><!--Size="100,200":表示椭圆的x轴和y轴-->
<BezierSegment Point1="130,30" Point2="40,140" Point3="150,150" /><!--贝赛尔曲线,p1 p2:控制点 p3:终点-->
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Path Stroke="Blue" Grid.Row="2" Data="M10,100 L100,100 L200,50 Z" />
</Grid>
效果
- 模糊效果
Radius
:范围 >=0 ,越大越模糊,默认值为5
<StackPanel>
<Button Padding="5" Margin="3" Content="Blurred(Radius=2默认为5)">
<Button.Effect>
<BlurEffect Radius="2" />
</Button.Effect>
</Button>
<Button Padding="5" Margin="3" Content="Blurred(Radius=5默认为5)">
<Button.Effect>
<BlurEffect />
</Button.Effect>
</Button>
<Button Padding="5" Margin="3" Content="Blurred(Radius=8默认为5)">
<Button.Effect>
<BlurEffect Radius="8" />
</Button.Effect>
</Button>
</StackPanel>
- 阴影效果
Color
:设置阴影颜色BlurRadius
:设置阴影模糊程度ShadowDepth
:设置阴影距离文本的距离Opacity
:设置阴影透明度Direction
:设置阴影逆时针旋转,0的话在文字右边,90在文字上面,180在文字左边
<StackPanel>
<TextBlock FontSize="20" Margin="5">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
<TextBlock.Text>有阴影的文本</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="20" Margin="5">
<TextBlock.Effect>
<DropShadowEffect Color="Red" />
</TextBlock.Effect>
<TextBlock.Text>蓝色阴影的文本</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="20" Margin="5">
<TextBlock.Effect>
<DropShadowEffect BlurRadius="2" />
</TextBlock.Effect>
<TextBlock.Text>BlurRadius=2的文本,默认是5</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="20" Margin="5">
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="50" />
</TextBlock.Effect>
<TextBlock.Text>ShadowDepth=50的文本,默认是5</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="20" Margin="5,50,5,5">
<TextBlock.Effect>
<DropShadowEffect Opacity="0.5" />
</TextBlock.Effect>
<TextBlock.Text>Opacity=0.5的阴影半透明文本</TextBlock.Text>
</TextBlock>
<TextBlock FontSize="20" Margin="5">
<TextBlock.Effect><!--设置阴影逆时针旋转,0的话在文字右边,90在文字上面,180在文字左边-->
<DropShadowEffect Direction="90" />
</TextBlock.Effect>
<TextBlock.Text>Direction的文本,默认315</TextBlock.Text>
</TextBlock>
</StackPanel>
基本动画
- DoubleAnimation代码实现方式
From
:初始值To
:最终值Duration
:持续时间AutoReverse
:自动翻转动画FillBehavior
:
FillBehavior.HoldEnd
:保持最终状态FillBehavior.Stop
:立即返回最初的动画前的状态
Completed
:动画完成后运行的函数
private void button1_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation widthAnimation = new DoubleAnimation();
widthAnimation.To = this.Width - 30;
widthAnimation.From = 200; //从100开始到this.Width - 30
widthAnimation.Duration = TimeSpan.FromSeconds(1); //动画时间间隔
widthAnimation.AutoReverse = true; //设置动画翻转,返回到动画前状态(From优先),默认false
widthAnimation.Completed += aniamtion_Completed;
button1.BeginAnimation(Button.WidthProperty, widthAnimation);
button1.Width = 10;//无效,优先使用动画设置的属性,如果不设置widthAnimation.To,则动画会一直到宽度为10
DoubleAnimation heightAnimation = new DoubleAnimation();
heightAnimation.To = this.Height - 100;
heightAnimation.From = 200;
heightAnimation.Duration = TimeSpan.FromSeconds(1);
heightAnimation.FillBehavior = FillBehavior.Stop; //立即返回最初的动画前的状态
button1.BeginAnimation(Button.HeightProperty, heightAnimation);
}
private void aniamtion_Completed(object sender, EventArgs e)
{
button2.BeginAnimation(Button.WidthProperty, null);
button2.Width = 50;
}
BeginTime
:设置动画延时三秒SpeedRatio
:动画速度默认为1,如果设为2,则为2倍速度,那么时间只需要0.5倍的DurationAccelerationRatio= 0.3
:前30%秒加速,后面不变DecelerationRatio= 0.3
:如果紧跟着上个属性,那么接着后30%秒减速,再后面不变RepeatBehavior= new RepeatBehavior(2)
:重复2次
private void button_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation dAnimation = new DoubleAnimation();
dAnimation.From = ellipse.ActualWidth;
dAnimation.To = Height / 2;
dAnimation.Duration = TimeSpan.FromSeconds(1);
//dAnimation.BeginTime = TimeSpan.FromSeconds(3); //设置动画延时三秒
dAnimation.SpeedRatio = 2; //动画速度默认为1,如果设为2,则为2倍速度,那么事件只需要0.5s,跟Duration对应
//dAnimation.AutoReverse = true;
dAnimation.AccelerationRatio = 0.3; //前30%秒加速,后面不变
dAnimation.DecelerationRatio = 0.3; //接着后30%秒减速,再后面不变
dAnimation.RepeatBehavior = new RepeatBehavior(2); //重复2次
ellipse.BeginAnimation(Ellipse.WidthProperty, dAnimation);
ellipse.BeginAnimation(Ellipse.HeightProperty, dAnimation);
}
- 故事板 Storyboard
<Window.Resources>
<Style x:Key="GrowButtonStyle">
<Style.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" From="160" To="300" Duration="0:0:2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Height="23" Content="button">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" From="160" To="300" Duration="0:0:2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource GrowButtonStyle}" Width="75" Height="23" Content="button1"></Button>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource GrowButtonStyle}" Width="75" Height="23" Content="同步动画">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard><!--保证了两个动画同时进行-->
<DoubleAnimation Storyboard.TargetProperty="Width" From="160" To="300" Duration="0:0:2"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="Height" From="160" To="300" Duration="0:0:3"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
控制播放
CurrentTimeInvalidated
:时间线更新时运行的事件BeginStoryboard
:开始动画PauseStoryboard
:暂停动画ResumeStoryboard
:恢复动画StopStoryboard
:结束动画
<Window.Triggers>
<EventTrigger SourceName="button" RoutedEvent="Button.Click">
<BeginStoryboard Name="fadeStoryBoardBegin">
<Storyboard CurrentTimeInvalidated="Storyboard_CurrentTimeInvalidated">
<DoubleAnimation Storyboard.TargetName="image" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:5"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="pause" RoutedEvent="Button.Click">
<PauseStoryboard BeginStoryboardName="fadeStoryBoardBegin"></PauseStoryboard>
</EventTrigger>
<EventTrigger SourceName="resume" RoutedEvent="Button.Click">
<ResumeStoryboard BeginStoryboardName="fadeStoryBoardBegin"></ResumeStoryboard>
</EventTrigger>
<EventTrigger SourceName="stop" RoutedEvent="Button.Click">
<StopStoryboard BeginStoryboardName="fadeStoryBoardBegin"></StopStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid>
<Image Source="sky.jpg"></Image>
<Image Name="image" Source="ss.jpg" Stretch="Fill"></Image>
</Grid>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Name="button" Content="启动动画" Margin="5" Padding="10,2"></Button>
<Button Name="pause" Content="暂停动画" Margin="5" Padding="10,2"></Button>
<Button Name="resume" Content="恢复动画" Margin="5" Padding="10,2"></Button>
<Button Name="stop" Content="终止动画" Margin="5" Padding="10,2"></Button>
</StackPanel>
<ProgressBar Grid.Row="2" Margin="0,5" Name="progressBar" Height="15" Minimum="0" Maximum="1"></ProgressBar>
</Grid>
动画缓动
- ElasticEase:弹性缓解
- EasingMode:
- EaseIn:开始时振荡
- EaseOut:结束时振荡
- EaseInOut:都振荡
- Oscillations:振荡次数
- EasingMode:
- BounceEase:反弹缓解
- EasingMode:
- EaseIn:开始时振荡
- EaseOut:结束时振荡
- EaseInOut:都振荡
- Bounces:反弹次数
- EasingMode:
<Grid>
<Button Name="cmdGrow" Width="300" Height="60" Content="会变长的按钮">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="cmdGrow" Storyboard.TargetProperty="Width" To="400" Duration="0:0:1.5">
<DoubleAnimation.EasingFunction>
<!--<ElasticEase EasingMode="EaseOut" Oscillations="10"></ElasticEase>-->
<BounceEase EasingMode="EaseOut" Bounces="3"></BounceEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="cmdGrow" Storyboard.TargetProperty="Width" Duration="0:0:3"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
动画性能
Timeline.DesiredFrameRate
:设置帧数ClipToBounds="True"
:设置不超过边框,即超过边框后不显示
<Window.Resources>
<BeginStoryboard x:Key="beginStoryboard">
<Storyboard Timeline.DesiredFrameRate="{Binding ElementName=tetFrameRate,Path=Text}"><!--帧数-->
<DoubleAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Left)" From="0" To="300" Duration="0:0:5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Top)" From="300" To="0" AutoReverse="True" Duration="0:0:2.5" DecelerationRatio="1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<StaticResource ResourceKey="beginStoryboard"></StaticResource>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Grid Background="LightGoldenrodYellow">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Border Background="White" BorderBrush="DarkGray" BorderThickness="3" Width="300" Height="300" HorizontalAlignment="Center" VerticalAlignment="Center">
<Canvas ClipToBounds="True"><!--不超过边框-->
<Ellipse Name="ellipse" Fill="Red" Width="10" Height="10" ></Ellipse>
</Canvas>
</Border>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" Margin="10">
<TextBlock VerticalAlignment="Center" xml:space="preserve">设置帧率</TextBlock>
<TextBox Width="50" Name="tetFrameRate">60</TextBox>
</StackPanel>
<Button Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Content="重置" Padding="3" Margin="3">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<StaticResource ResourceKey="beginStoryboard"></StaticResource>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
动态变换
RepeatBehavior="Forever"
:永远重复
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
<Setter Property="Padding" Value="20,15"></Setter>
<Setter Property="Margin" Value="2"></Setter>
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform></RotateTransform>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="rotatedStoryboardBegin">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
<!--<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform></RotateTransform>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="rotatedStoryboardBegin">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.Angle" To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.Angle" Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>-->
</Style>
</Window.Resources>
<StackPanel Margin="5" Button.Click="cmd_Clicked">
<Button>1</Button>
<Button>2</Button>
<Button>3</Button>
<Button>4</Button>
<TextBlock Name="textBlock" Margin="5"></TextBlock>
</StackPanel>
动态改变画刷
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin" From="0.7,0.3" To="0.3,0.7" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever"></PointAnimation>
<ColorAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientStops[1].Color" To="Blue" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Grid>
<Ellipse Name="ellipse" Margin="5">
<Ellipse.Fill>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.3">
<GradientStop Color="White" Offset="0"></GradientStop>
<GradientStop Color="Red" Offset="1"></GradientStop>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Name="visual" HorizontalAlignment="Center" VerticalAlignment="Center" Content="VisualTest">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard Completed="storyboardCompleted">
<DoubleAnimation Storyboard.TargetName="rectangle" Storyboard.TargetProperty="RenderTransform.Children[0].AngleY" To="180" Duration="0:0:5" AutoReverse="True"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle" Storyboard.TargetProperty="RenderTransform.Children[1].Angle" To="180" Duration="0:0:5" AutoReverse="True"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle" Storyboard.TargetProperty="Opacity" To="0.1" Duration="0:0:5" AutoReverse="True"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Rectangle Grid.Row="1" Name="rectangle" Width="100" Stretch="Uniform" ClipToBounds="False" RenderTransformOrigin="0.5,0.5">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=visual}"></VisualBrush>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<SkewTransform CenterX="0.5"></SkewTransform>
<RotateTransform CenterX="0.5" CenterY="0.5"></RotateTransform>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
动态改变像素着色器
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="2"></Setter>
<Setter Property="Padding" Value="5"></Setter>
<Setter Property="Effect">
<Setter.Value>
<BlurEffect Radius="10"></BlurEffect>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Effect.Radius" To="0" Duration="0:0:2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Effect.Radius" Duration="0:0:2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Margin="5">
<Button>1</Button>
<Button>2</Button>
<Button>3</Button>
<Button>4</Button>
</StackPanel>
关键帧动画
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin" AutoReverse="True" RepeatBehavior="Forever">
<!--线性关键帧-->
<!--<LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:12"></LinearPointKeyFrame>-->
<!--离散关键帧-->
<!--<DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:12"></DiscretePointKeyFrame>-->
<!--缓动关键帧-->
<DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></DiscretePointKeyFrame>
<EasingPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5">
<EasingPointKeyFrame.EasingFunction>
<CircleEase></CircleEase>
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
</PointAnimationUsingKeyFrames>
<ColorAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientStops[1].Color" To="Blue" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Grid>
<Ellipse Name="ellipse" Margin="5">
<Ellipse.Fill>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.3">
<GradientStop Color="White" Offset="0"></GradientStop>
<GradientStop Color="Red" Offset="1"></GradientStop>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
利用贝塞尔曲线设置动画
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Left)">
<SplineDoubleKeyFrame KeyTime="0:0:5" Value="250" KeySpline="0.25,0 0.5,0.7"></SplineDoubleKeyFrame><!--样条关键帧 贝赛尔曲线-->
<SplineDoubleKeyFrame KeyTime="0:0:10" Value="500" KeySpline="0.25,0.8 0.2,0.4"></SplineDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Canvas.Left)" To="500" Duration="0:0:10"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Canvas>
<Ellipse Name="ellipse" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>
<Ellipse Name="ellipse1" Canvas.Left="0" Canvas.Top="150" Fill="Blue" Width="10" Height="10"></Ellipse>
</Canvas>
基于路径的动画
SweepDirection="Clockwise"
:扫描方向为顺时针Point
:弧从0,0开始,point指弧的终点Size
:指椭圆的x和y的比例
<Window.Resources>
<PathGeometry x:Key="path">
<PathFigure IsClosed="True">
<ArcSegment Point="100,200" Size="15,10" SweepDirection="Clockwise"></ArcSegment>
<ArcSegment Point="400,50" Size="5,5"></ArcSegment>
</PathFigure>
</PathGeometry>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingPath Storyboard.TargetName="image" Storyboard.TargetProperty="(Canvas.Left)" PathGeometry="{StaticResource path}" Duration="0:0:10" RepeatBehavior="Forever" Source="X"></DoubleAnimationUsingPath>
<DoubleAnimationUsingPath Storyboard.TargetName="image" Storyboard.TargetProperty="(Canvas.Top)" PathGeometry="{StaticResource path}" Duration="0:0:10" RepeatBehavior="Forever" Source="Y"></DoubleAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Canvas Margin="10">
<Path Stroke="Red" StrokeThickness="1" Data="{StaticResource path}" Canvas.Left="10" Canvas.Top="10"></Path>
<Image Name="image">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="LightSteelBlue">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry Center="10,10" RadiusX="9" RadiusY="4"></EllipseGeometry>
<EllipseGeometry Center="10,10" RadiusX="4" RadiusY="9"></EllipseGeometry>
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness="1" Brush="Black"></Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Canvas>