• WPF深入浅出代码案例


    画一个椭圆

    <Window x:Class="WpfApp3.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:WpfApp3"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Ellipse Name="rectangle"  Width="90" Height="90">
                <Ellipse.Fill>
                    <RadialGradientBrush GradientOrigin="0.25,0.25" RadiusX="0.75" RadiusY="0.75">
                        <RadialGradientBrush.GradientStops>
                            <GradientStop Color="White" Offset="0"/>
                            <GradientStop Color="Black" Offset="0.65"/>
                            <GradientStop Color="Gray" Offset="0.8"/>
                        </RadialGradientBrush.GradientStops>
                    </RadialGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
        </Grid>
    </Window>
    xaml

    GradientOrigin:定义渐变开始的二维焦点的位置。

    RadiusX:径向渐变的最外面圆的水平半径。

    RadiusY:径向渐变的最外面圆的垂直半径。

    GradientStop:渐变中转换点的位置和颜色。

     ------------------------------------------------------------------------------------------

    标记扩展

            <Slider Name="slider" HorizontalAlignment="Left" Margin="92,203,0,0" VerticalAlignment="Top" Width="205"/>
            <TextBlock Text="{Binding ElementName=slider,Path=Value ,Mode=OneWay}" Margin="96,259,244,132"></TextBlock>

    ------------------------------------------------------------------------------------------

    4.x:名称空间

    x:key

    为了在XAML中使用string类,需要

    xmlns:sys="clr-namespace:System;assembly=mscorlib"

    在XAML调用时,

    <TextBox Text="{StaticResource ResourceKey=my}"        Margin="255,314,0,0"   VerticalAlignment="Top" Width="120"/>

    在c#中调用

                string str = this.FindResource("my") as string;
                this.textbox1.Text = str;

    ------------------------------------------------------------------------------------------

    x:type  案例代码一直提示未找到MyButton   

    打开工程属性------生成------目标平台:如果原来是Any CPU,则切换为x86或x64,保存!然后清理解决方案!重新生成解决方案!

    ------------------------------------------------------------------------------------------

    x:null

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Window.Resources>
            <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
                <Setter Property="Width" Value="60"/>
                <Setter Property="Height" Value="36"/>
                <Setter Property="Margin" Value="5"/>
            </Style>
            
        </Window.Resources>
        <StackPanel Background="LightSlateGray">
            <Button  Content="ok"/>
            <Button  Content="ok"/>
            <Button  Content="ok"/>
            <Button  Content="ok" Style="{x:Null}"/>
        </StackPanel>
    </Window>
    View Code

    x:array

    <Window x:Class="WpfApp4.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:sys="clr-namespace:System;assembly=mscorlib"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <StackPanel Background="LightSlateGray">
            <ListBox>
                <ListBox.ItemsSource>
                    <x:Array Type="sys:String">
                        <sys:String>tom</sys:String>
                        <sys:String>jack</sys:String>
                        <sys:String>tony</sys:String>
                    </x:Array>
                </ListBox.ItemsSource>
            </ListBox>
        </StackPanel>
    </Window>
    View Code

    x:static

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="{x:Static local:MainWindow.WindowsTitle}" Height="450" Width="800">
        
        <StackPanel Background="LightSlateGray">
            <TextBox Text="{x:Static local:MainWindow.ShowText}"/>
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public static string WindowsTitle = "啊哈哈哈哈";
            public static string ShowText { get { return "abandon"; } }
    
            public MainWindow()
            {
                InitializeComponent();
            }
           
        }
    }
    cs

    5.控件与布局

    6.深入浅出话binding

    让binding源的对象具有自动通知binding 自己属性值已变化

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <StackPanel>
            <TextBlock x:Name="textblockname"></TextBlock>
            <Button Height="50" Click="Button_Click"></Button>
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            Student stu = new Student();
            public MainWindow()
            {
                InitializeComponent();
    
               
                Binding userbinding = new Binding();
                userbinding.Source = stu;
                userbinding.Path = new PropertyPath("Name");
                //使用binding绑定数据源和binding目标
    
                BindingOperations.SetBinding(this.textblockname, TextBlock.TextProperty, userbinding);//绑定的绑定目标 绑定的目标属性 描述绑定的BindingBase对象
            }
    
    
    
            class Student : INotifyPropertyChanged
            {
                public event PropertyChangedEventHandler PropertyChanged;
                private string name;
                public string Name
                {
                    get { return name; }
                    set 
                    {
                        name = value;
                        if (this.PropertyChanged != null)
                        {
                            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
                        }
                    }                
                }
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                stu.Name += "1";
            }
        }
    }
    cs

     

    显式的为数据设置DataTemplate

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <StackPanel>
     
            
             <TextBox x:Name="textBox1" Text="{Binding Path=Id}"  BorderBrush="Aqua" Margin="5"></TextBox>
            <ListBox x:Name="listbox1" Height="100" Margin="5">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Path=Id}" Background="Pink" Width="30"/>
                            <TextBlock Text="{Binding Path=Name}" Background="Blue"  Width="50"/>
                            <TextBlock Text="{Binding Path=Age}" Background="Red" Width="80"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
           
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
    
                InitializeComponent();
    
                List<Studetn1> stulist = new List<Studetn1>()
                {
                    new Studetn1(){ Id=0,Name="tim",Age=29 },
                    new Studetn1(){ Id=2,Name="tom",Age=22 },
                    new Studetn1(){ Id=3,Name="vina",Age=230 },
                    new Studetn1(){ Id=4,Name="mike",Age=20 },
    
                };
    
                this.listbox1.ItemsSource = stulist;
                //this.listbox1.DisplayMemberPath = "Name";
    
    
                this.textBox1.SetBinding(TextBox.TextProperty, new Binding("SelectedItem.Id") { Source = this.listbox1 });
    
            }
            
            public class Studetn1
            {
                public int Id { get; set; }
                public string Name { get; set; }
                public int Age { get; set; }
    
            }
    
    
    
        }
    }
    cs

    在使用集合类型作为列表控件的ItemsSource时一般会考虑使用ObservableCollection<T>代替List<T>,因为ObservableCollection<T>类实现了INotifyCollectionChange和INotifyPropertyChange接口,能把集合的变化立刻通知他的列表控件。

    6.3.8  使用ADO.NET对象作为Binding的源  后面看实例

    6.3.9  使用XML数据作为Binding的源

    .NET Framework提供了两套处理XML数据的类库

    符合DOM(Document Object Model 文档对象模型)

    以LINQ(Language-Intergrated Query 语言集成查询)

    注意:当使用XML数据作为Binding的Source时我们将使用XPath 属性而不是Path属性来指定对象。

    基于DOM标准的XML类库使用

    如何建立XML文件

     XML文件内容如下

    <?xml version="1.0" encoding="utf-8"?>
    <StudentList>
        <Student Id="1">
            <Name>Time1</Name>
        </Student>
        <Student Id="2">
            <Name>Time2</Name>
        </Student>
        <Student Id="3">
            <Name>Time3</Name>
        </Student>
        <Student Id="4">
            <Name>Time4</Name>
        </Student>
    </StudentList>
    XML
    Xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
            }
           
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(@"D:\suwen\Desktop\XMLFile1.xml");
                XmlDataProvider xdp = new XmlDataProvider();
                xdp.Document = doc;
                //使用Xpath选择需要暴露的数据
                //现在时需要暴露一组Student
                xdp.XPath = @"StudentList/Student";
                this.listViewStudents.DataContext = xdp;
                this.listViewStudents.SetBinding(ListView.ItemsSourceProperty, new Binding());
            }
        }
    }
    cs

    使用LINQ检索结果作为Binding的源

    在Button被单击的时候显示一个Students集合类型对象

    从一个已经填充好的List<Student>对象中检索出所有名字以之母T开头的学生,代码如下

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <StackPanel Background="AliceBlue">
            <ListView x:Name="listViewStudents" Height="130" Margin="5">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Id" Width="80"
                                        DisplayMemberBinding="{Binding Id}"/>
                        <GridViewColumn Header="Name" Width="120"
                                        DisplayMemberBinding="{Binding Name}"/>
                        <GridViewColumn Header="Age" Width="120"
                                        DisplayMemberBinding="{Binding Age}"/>
                    </GridView>
                </ListView.View>
            </ListView>
            <Button Content="load" Click="Button_Click_2"/>
        </StackPanel>
    </Window>
    Xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
            }
            public class Student
            {
                public int Id { get; set;  }
                public string Name { get; set; }
                public int Age { get; set; }
            }
           
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
    
                List<Student> stulist = new List<Student>()
                {
                    new Student(){ Id=0,Name="Tim",Age=20},
                    new Student(){ Id=1,Name="T5im",Age=21},
    
                };
                this.listViewStudents.ItemsSource = from stu in stulist where stu.Name.StartsWith("T") select stu;
                    
            }
        }
    }
    cs

    6.3.11  使用ObjectDataProvider对象作为Binding的Source

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <StackPanel Background="AliceBlue">
           
            <Button Content="load" Click="Button_Click_2"/>
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
            }
            public class Calculator
            {
                public string Add(string arg1, string arg2)
                {
                    double x = 0;
                    double y = 0;
                    double z = 0;
                    if (double.TryParse(arg1, out x) && double.TryParse(arg2, out y))
                    {
                        z = x + y;
                        return z.ToString();
                    }
                    return "input Error";
                }
            
    
            }
           
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
    
                ObjectDataProvider odp = new ObjectDataProvider();
                odp.ObjectInstance = new Calculator();
                odp.MethodName = "Add";
                odp.MethodParameters.Add("100");
                odp.MethodParameters.Add("300");
                MessageBox.Show(odp.Data.ToString());
            }
        }
    }
    cs

    6.3.11  使用Bingding的RelativeSource

    不确定作为Source的对象叫什么名字,但知道它作为Binding目标的对象在UI布局上有相对关系。

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <Grid x:Name="grid1" HorizontalAlignment="Left" Height="178" Margin="65,63,0,0" VerticalAlignment="Top" Width="532">
            <DockPanel x:Name="dockPanel1" HorizontalAlignment="Left" Height="140" LastChildFill="False" Margin="84,44,0,-6" VerticalAlignment="Top" Width="369">
                <StackPanel x:Name="stackPanel1" Height="140" VerticalAlignment="Top" Width="254">
                    <Grid x:Name="grid2" Height="100">
                        <Grid x:Name="grid3" Height="100">
                            <TextBlock x:Name="textBlock1" HorizontalAlignment="Left" Margin="103,46,0,0" TextWrapping="Wrap" VerticalAlignment="Top"><Run Text="TextBlock"/></TextBlock>
                        </Grid>
                        
                    </Grid>
                </StackPanel>
            </DockPanel>
        </Grid>
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                RelativeSource rs = new RelativeSource(RelativeSourceMode.FindAncestor);
    
                rs.AncestorLevel = 2;//以Binding目标控件为起点的层级偏移量
                rs.AncestorType = typeof(Grid);//告诉Binding寻找哪个类型的对象那个作为自己的源,不是这个类型的对象会被跳过
                Binding binding = new Binding("Name") { RelativeSource = rs };
                this.textBlock1.SetBinding(TextBlock.TextProperty, binding);
            }   
    
        }
    }
    cs

    6.4  Binding对数据的转化与校验

    6.4.1  binding的数据校验

    Binding用于数据有效性校验的关卡是它的ValidationRules

    textbox 显示slider的数据,如果数据校验失败显示错误

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <Grid x:Name="grid1" HorizontalAlignment="Left" Height="178" Margin="65,63,0,0" VerticalAlignment="Top" Width="532">
            <TextBox x:Name="TextBox1" HorizontalAlignment="Left" Height="23" Margin="189,113,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
            <Slider x:Name="Slider1" Minimum="0" Maximum="110" HorizontalAlignment="Left" Margin="100,59,0,0" VerticalAlignment="Top" Width="327"/>
    
        </Grid>
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                Binding binding = new Binding("Value") { Source = this.Slider1 };
                binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                RangeValidationRule rvr = new RangeValidationRule();
                rvr.ValidatesOnTargetUpdated = true;
    
                binding.ValidationRules.Add(rvr);
                binding.NotifyOnValidationError = true;
                this.TextBox1.SetBinding(TextBox.TextProperty, binding);
    
                this.TextBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));
            }
    
            //需要一个ValidationRule的派生类
            public class RangeValidationRule : ValidationRule
            {
                //实现Validate方法
                public override ValidationResult Validate(object value, CultureInfo cultureInfo)
                {
                    double d = 0;
                    if (double.TryParse(value.ToString(), out d))
                    {
                        if (d >= 0 && d <= 100)
                        {
                            return new ValidationResult(true, null);
                        }
                    }
                    return new ValidationResult(false, "Validation Failed");
                }
    
            }
    
            //用于侦听校验错误事件的事件处理器如下:
            void ValidationError(object sender, RoutedEventArgs e)
            {
                if (Validation.GetErrors(this.TextBox1).Count > 0)
                {
                    this.TextBox1.ToolTip = Validation.GetErrors(this.TextBox1)[0].ErrorContent.ToString();
                }
            }
    
        }
    }
    cs

    6.4.2  binding的数据转化

    涉及,飞机的category单向转换为string(XAML编译器能把string对象解析为图片资源),state与bool?类型之间的双向转化

    按下load在listbox显示飞机的类别,名称,状态,,按下save可以将信息保存在txt文件内容。

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <Window.Resources>
            <local:CategoryToSourceConventer x:Key="cts"/>
            <local:StateToNullableBollConventer x:Key="stnb"/>
        </Window.Resources>
    
        <StackPanel Background="LightBlue">
            <ListBox x:Name="listBoxPlane" Height="160" Margin="5">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Width="20" Height="20"  
                                   Source="{Binding Path=Category,Converter={StaticResource cts}}"/>
    
                            <TextBlock Text="{Binding Path=Name}" Width="60" Margin="80,0"/>
                            <CheckBox IsThreeState="True"
                                           IsChecked="{Binding Path=State,Converter={StaticResource stnb}}"/>
                                   
                        </StackPanel>
                    </DataTemplate>
                    
                </ListBox.ItemTemplate>
                
            </ListBox>
            <Button x:Name="buttonLoad" Content="Load" Height=" 25" Margin="5,0" Click="buttonLoad_Click"/>
            <Button x:Name="buttonSave" Content="Save" Height=" 25" Margin="5,5" Click="buttonSave_Click"/>
    
        </StackPanel>
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void buttonLoad_Click(object sender, RoutedEventArgs e)
            {
                List<Plane> palneList = new List<Plane>()
                {
                new Plane(){ Category=Category.Bomber,Name="B-1",State=State.Unknown},
                new Plane(){ Category=Category.Bomber,Name="B-2",State=State.Unknown},
                new Plane(){ Category=Category.Fighter,Name="F-22",State=State.Unknown},
                new Plane(){ Category=Category.Fighter,Name="Su-47",State=State.Unknown},
                new Plane(){ Category=Category.Bomber,Name="B-52",State=State.Unknown},
                new Plane(){ Category=Category.Fighter,Name="J-10",State=State.Unknown},
                };
                this.listBoxPlane.ItemsSource = palneList;
    
            }
    
            private void buttonSave_Click(object sender, RoutedEventArgs e)
            {
                StringBuilder sb = new StringBuilder();
                foreach (Plane p in listBoxPlane.Items)
                {
                    sb.AppendLine(string.Format("Catedory={0} Name={1},State={2}", p.Category, p.Name, p.State));
                }
                File.WriteAllText(@"D:\PlaneList.txt", sb.ToString());
            }
        }
    
    
        //轰炸机的类别,轰炸机的状态,飞机
        public enum Category
        {
            Bomber,
            Fighter
        }
        public enum State
        {
            Available,
            Locked,
            Unknown
        }
    
        public class Plane
        {
            public Category Category { get; set; }
            public string Name { get; set; }
            public State State { get; set; }
    
        }
    
        public class CategoryToSourceConventer : IValueConverter
        {
            //将Category转换为Uri
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                Category c = (Category)value;
                switch (c)
                {
                    case Category.Bomber:
                        return @"\Icon\Bomber.png";
                    case Category.Fighter:
                        return @"\Icon\Fighter.png";
                    default:
                        return null;
                }
            }
            //不会被调用
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    
        public class StateToNullableBollConventer : IValueConverter
        {
            //将State转换为boll?
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                State s = (State)value;
                switch (s)
                {
                    case State.Locked:
                        return false;
                    case State.Available:
                        return true;
                    case State.Unknown:
                    default:
                        return null;
                }
            }
            //boll?转换为State
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                bool? nb = (bool?)value;
                switch (nb)
                {
                    case true:
                        return State.Available;
                    case false:
                        return State.Locked;
                    case null:
                    default:
                        return State.Unknown;
                }
            }
        }
    }
    cs

    6.5  MultiBinding(多路Binding)

     UI需要显示的信息由不止一个数据源来决定,需要使用MultBinding

    需求:有一个用于新用户注册的UI(包含4个TextBox和1个Button)还有如下一些限定

    第一,第二TextBox输入用户名,要求内容一致

    第三,第四TextBox输入用户E-Mail,要求内容一致。

    当TextBox全部输入一致时,Button可用

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <StackPanel Background="Lavender">
            <TextBox x:Name="textBox1" Height="23" Margin="5"></TextBox>
            <TextBox x:Name="textBox2" Height="23" Margin="5,0"></TextBox>
            <TextBox x:Name="textBox3" Height="23" Margin="5"></TextBox>
            <TextBox x:Name="textBox4" Height="23" Margin="5,0"></TextBox>
            <Button x:Name="button1" Content="Submit" Width="80" Margin="5"/>
    
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                this.SetMultiBinding();
    
            }
            private void SetMultiBinding()
            {
                    Binding b1 = new Binding("Text") { Source = this.textBox1 };
                    Binding b2 = new Binding("Text") { Source = this.textBox2 };
                    Binding b3 = new Binding("Text") { Source = this.textBox3 };
                    Binding b4 = new Binding("Text") { Source = this.textBox4 };
    
                MultiBinding mb = new MultiBinding() { Mode = BindingMode.OneWay };
                mb.Bindings.Add(b1);
                mb.Bindings.Add(b2);
                mb.Bindings.Add(b3);
                mb.Bindings.Add(b4);
    
                mb.Converter = new LogonMultiBindingConvert();
    
                this.button1.SetBinding(Button.IsEnabledProperty, mb);
            }
    
            public class LogonMultiBindingConvert : IMultiValueConverter
            {
                public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
                {
                    if (!values.Cast<string>().Any(text=>string.IsNullOrEmpty(text))
                    
                        && values[0].ToString() == values[1].ToString()
                        && values[2].ToString() == values[3].ToString())
                    {
                        return true;
                    }
                    return false;
                }
    
                public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
                {
                    throw new NotImplementedException();
                }
    
               
            }
    
    
    
        }
    }
    
    
       
    cs

    7.深入浅出话属性

    7.22  声明和使用依赖属性

    两个TextBox,按下button后,第二个TextBox显示第一个TextBox的内容

    <Window x:Class="WpfApp4.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:WpfApp4"
            mc:Ignorable="d"
            Title="123" Height="450" Width="800">
        <StackPanel Background="Lavender">
            <TextBox x:Name="textBox1" Height="23" Margin="5"></TextBox>
            <TextBox x:Name="textBox2" Height="23" Margin="5,0"></TextBox>
            <Button x:Name="button1" Content="dependency" Width="80" Margin="5" Click="button1_Click"/>
    
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                
    
            }
    
            public class Student : DependencyObject
            {
                public static readonly DependencyProperty NameProperty =
                        DependencyProperty.Register("Name", typeof(string), typeof(Student));
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                Student stu = new Student();
                stu.SetValue(Student.NameProperty, this.textBox1.Text);
                textBox2.Text = (string)stu.GetValue(Student.NameProperty);
            }
        }
    }
    
    
       
    cs

    提示:在一个类中声明依赖属性时,并不需要手动声明、注册并使用CLR属性封装,只需要输入propdp,,Visual Studio 提示列表中会有一项高亮显示,此时连续按下两下Tab键,,一个标准的依赖属性就声明好了。

    8.深入浅出话事件

    8.3.3  自定义路由事件

     在ListBox显示路由事件发生时间

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="Route Event"
            mc:Ignorable="d"
            x:Name="window_1"  Height="450" Width="800"
             local:TimeButton.ReportTime="ReportTimeHandler"
            >
        <Grid x:Name="grid_1"  local:TimeButton.ReportTime="ReportTimeHandler">
            <Grid x:Name="grid_2"   local:TimeButton.ReportTime="ReportTimeHandler">
                <Grid x:Name="grid_3"   local:TimeButton.ReportTime="ReportTimeHandler">
                    <StackPanel x:Name="stackPanel_1"  local:TimeButton.ReportTime="ReportTimeHandler"
                        >
                        <ListBox x:Name="listBox"   local:TimeButton.ReportTime="ReportTimeHandler"/>
                        <local:TimeButton x:Name="timeButton" Width="80" Height="80" 
                        Content="报时"  local:TimeButton.ReportTime="ReportTimeHandler"/>
                        
                    </StackPanel>
    
    
    
    
                </Grid>
            </Grid>
        </Grid>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
    
            }
            private void ReportTimeHandler(object sender, ReporTimeEventArgs e)
            {
                FrameworkElement element = sender as FrameworkElement;
                string timeStr = e.ClickTime.ToLongTimeString();
                string contnet = string.Format("{0}到达{1}", timeStr, element.Name);
                this.listBox.Items.Add(contnet);
    
    
            }
    
    
        }
        //用于承载时间消息的事件参数
        class ReporTimeEventArgs : System.Windows.RoutedEventArgs
        {
            public ReporTimeEventArgs(RoutedEvent routedEvent, object source)
                : base(routedEvent, source) { }
            public DateTime ClickTime { get; set; }
        }
    
        class TimeButton : Button
        {
            //声明和注册路由事件
            public static readonly RoutedEvent ReporTimeEvent = EventManager.RegisterRoutedEvent
                ("ReportTime", RoutingStrategy.Bubble, typeof(EventHandler<ReporTimeEventArgs>), typeof(TimeButton));
    
            //CLR事件包装器
            public event RoutedEventHandler ReportTime
            {
                add { this.AddHandler(ReporTimeEvent, value); }
                remove { this.RemoveHandler(ReporTimeEvent, value); }
    
    
            }
    
            //激发路由事件,借用Click事件的激发方法
            protected override void OnClick()
            {
                base.OnClick();//保证Button原有功能正常使用
    
                ReporTimeEventArgs args = new ReporTimeEventArgs(ReporTimeEvent, this);
                args.ClickTime = DateTime.Now;
                this.RaiseEvent(args);
    
            }
            //ReportTimeEvent路由事件处理器
        }
    
    
    }
    cs

    8.3.3  RoutedEventArgs的Source与OriginalSource

    VisualTree与LogicalTree区别就在于LogicalTree的叶子结点是构成用户界面的控件,而VisualTree要连控件中的细微结构也算上。

    RoutedEventArgs两个属性,Source表示Logical上的消息源头,OriginalSource表示VisualTree上的源头

     8.3.4  事件也附加-深入浅出附加事件

    附加事件的宿主没有界面渲染功能,但是是可以使用附加事件与其他对象进行沟通。

    设计一个名为Student的类,如果Student实例Name属性值发生的变化就激发一个路由事件,使用界面元素来捕捉这个事件。

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="450" Width="800">
        <Grid x:Name="gridMain">
            <Button x:Name="button1" Content="OK" Width="80" Height="80" Click="button1_Click">
                
            </Button>
            
        </Grid>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                //为外层Grid添加路由事件侦听器
                Student.AddNameChangedHandler(
                    this.gridMain,
                    new RoutedEventHandler(this.StudentNameChangedHandler));
    
    
                    
    
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                Student stu = new Student { ID = 10, Name = "Tim" };
                stu.Name = "Tom";
                //准备事件消息并发送路由事件
                RoutedEventArgs arg = new RoutedEventArgs(Student.NameChangedEvent, stu);
                this.button1.RaiseEvent(arg);
            }
            //Grid捕捉到NameChangedEvent后的处理器
            private void StudentNameChangedHandler(object sender, RoutedEventArgs e)
            {
                MessageBox.Show((e.OriginalSource as Student).ID.ToString());
            }
        }
    
    
        public class Student
        {
            //声明定义路由事件
            public static readonly RoutedEvent NameChangedEvent = EventManager.RegisterRoutedEvent
                    ("NameChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Student));
    
            //为界面元素添加路由事件侦听
            public static void AddNameChangedHandler(DependencyObject d, RoutedEventHandler h)
            {
                UIElement e = d as UIElement;
                if (e != null)
                {
                    e.AddHandler(Student.NameChangedEvent, h);
                }
            }
            //移除侦听
            public static void RemoveNameChangedHandler(DependencyObject d, RoutedEventHandler h)
            {
                UIElement e = d as UIElement;
                if (e != null)
                {
                    e.RemoveHandler(Student.NameChangedEvent, h);
                }
            }
            public int ID { get; set; }
            public string Name { get; set; }
        }
    }
    cs

    9  深入浅出话命令

    9.1  命令系统的基本元素与关系

    9.1.1  命令系统的基本元素

    WPF的命令系统由几个基本要素构成

    命令(Comamand)实际上就是实现了ICommad接口的类

    命令源(CommandSource)即命令的发送者,是实现了IcommandSource接口的类

    命令目标(CommandTarget)命令将发送给谁,命令目标必须是实现了IInputElement接口的类

    命令关联(CommandBinding)负责把一些外围逻辑与命令关联起来

    9.1.2  基本元素之间的关系

    基本元素之间的关系体现在使用命令的过程中。命令使用大概分为如下几步:

    (1)创建命令类:及获得一个实现Icommand接口的类,

    (2)声明命令实例

    (3)指定命令的源

    (4)指定命令目标

    (5)设置命令关联

    9.1.3  小试命令

    需求:定义一个命令,使用Button来发送这个命令,当命令送达TextBox时,TextBox会被清空(如果TextBox中没有文字则命令不可以被发送)

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="450" Width="800">
        <StackPanel x:Name="stackPanel">
            <Button x:Name="button1" Content="send Command" Margin="5"  />
            <TextBox x:Name="textBoxA" Margin="5" Height="100" />
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                InitializeCommand();
                    
    
            }
    
            //声明并定义命令
            private RoutedCommand clearCmd = new RoutedCommand("Clear", typeof(MainWindow));
    
            private void InitializeCommand()
            {
                //把命令赋值给命令源(发送者)并指定快捷键
                this.button1.Command = this.clearCmd;
                this.clearCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));
                //指定命令目标
                this.button1.CommandTarget = this.textBoxA;
                //创建命令关联
                CommandBinding cb = new CommandBinding();
                cb.Command = this.clearCmd;         //只关注与clearCmd相关的事件
                    cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
                cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);
    
                //把命令关联安置在外围控件上
                this.stackPanel.CommandBindings.Add(cb);                 
            }
            //当探测命令是否可以执行是,此方法被调用
            void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (string.IsNullOrEmpty(this.textBoxA.Text))
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.Handled = true;
                }
                //避免继续向上传而降低程序性能
                e.Handled = true;
            }
            //当命令到达后,命令被调用
            void cb_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                this.textBoxA.Clear();
                //避免继续向上传而降低程序性能
                e.Handled = true;
            }
    
    
        }
    
    
        
    }
    cs

    因为CanExecute事件的激发频率比较高,为避免降低性能处理完后,建议把e.Handled设为true

    CommandBinding一定哟啊设置在命令目标的外围控件上,不然呢无法捕捉到CanExecute和Executed等路由事件。

    9.1.4  WPF的命令库

    WPF准备了一些便捷的命令库

    ApplicationCommands

    ComponentCommands

    NavigationCommands

    MediaCommands

    EditingCommans

    9.1.5  命令参数

    运行程序,当TextBox中没有内容时,两个按钮均不可用;当输入文字后,按钮变可用,单击按钮,LIstBox会加入不同条目

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="450" Width="800">
        <Grid Margin="6">
            <Grid.RowDefinitions>
                <RowDefinition Height="24"/>
                <RowDefinition Height="4"/>
                <RowDefinition Height="24"/>
                <RowDefinition Height="4"/>
                <RowDefinition Height="24"/>
                <RowDefinition Height="4"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <!--命令和命令参数 -->
            <TextBlock Text="Name:" VerticalAlignment="Center" HorizontalAlignment="Left"
                    Grid.Row="0"/>
            <TextBox x:Name="nameTextBox" Margin="60,0,0,0"  
                    Grid.Row="0"/>
            <Button Content="New Teacher" Command="New"  CommandParameter="Teacher"
                    Grid.Row="2"/>
            <Button Content="New Teacher" Command="New"  CommandParameter="Teacher"
                    Grid.Row="2"/>
            <Button Content="New Student" Command="New"  CommandParameter="Student"
                    Grid.Row="4"/>
            <ListBox x:Name="listBoxNewItems" Grid.Row="6"/>
        </Grid>
        <!--为窗体添加CommandBinding-->
        <Window.CommandBindings>
            <CommandBinding Command="New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
        </Window.CommandBindings>
        
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                
                    
    
            }
    
            private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (string.IsNullOrEmpty(this.nameTextBox.Text))
                {
                    e.CanExecute = false;
    
                }
                else
                {
                    e.CanExecute = true;
                }
            }
    
            private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                string name = this.nameTextBox.Text;
                if (e.Parameter.ToString()=="Teacher")
                {
                    this.listBoxNewItems.Items.Add(string.Format("New Teacher:{0},学而不厌,诲人不倦。", name));
                }
                if (e.Parameter.ToString() == "Student")
                {
                    this.listBoxNewItems.Items.Add(string.Format("New Teacher:{0},好好学习,天天向上。", name));
                }
            }
        }
    
    
        
    }
    cs

    9.1.6  命令与Binding的结合

    9.2  近观命令

    9.2.1  ICommand接口与RoutedCommand

    9.2.2  自定义Command

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="450" Width="800">
        <StackPanel>
            <local:MyCommandSource x:Name="ctrlClear" Margin="10">
                <TextBlock Text="清除" FontSize="16" TextAlignment="Center" Background="LightBlue" Width="80" />
            </local:MyCommandSource>
            <local:MiniView x:Name="miniView"/>
        </StackPanel>
    </Window>
    mainWindow.xaml
    <UserControl x:Class="WpfApp4.MiniView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApp4"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <Border CornerRadius="5" BorderBrush="LawnGreen" BorderThickness="5">
            <StackPanel>
                <TextBox x:Name="textBox1" Margin="5" />
                <TextBox x:Name="textBox2" Margin="5,0" />
                <TextBox x:Name="textBox3" Margin="5" />
                <TextBox x:Name="textBox4" Margin="5,0" />
            </StackPanel>
        </Border>
    </UserControl>
    miniWindow.xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                //声明命令并使用命令源和目标与之关联
                ClearCommand clearCmd = new ClearCommand();
                this.ctrlClear.Command = clearCmd;
                this.ctrlClear.CommandTarget = this.miniView;
    
            }
    
        }
    
        public interface IView
        { 
            //属性
            bool isChanged { get; set; }
            //方法
            void SetBinding();
            void Refresh();
            void Clear();
            void Save();
        }
        //自定义命令
        public class ClearCommand : ICommand
        {
            //当命令可执行状态发生变化时,应被激发
            public event EventHandler CanExecuteChanged;
            //用于判断命令是否可以执行(暂不实现)
            public bool CanExecute(object parament)
            {
                throw new NotImplementedException();
            }
    
            //命令执行带有业务相关的Clear逻辑
            public void Execute(object parameter)
            {
                IView view = parameter as IView;
                if (view!=null)
                {
                    view.Clear();
                }
            }
        }
    
        //自定义命令源
        public class MyCommandSource : UserControl, ICommandSource
        { 
            //继承自ICommandSource的三个属性
            public ICommand Command { get; set; }
            public object CommandParameter { get; set; }
            public IInputElement CommandTarget { get; set; }
    
            //在组件被单击时连带执行命令
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                base.OnMouseLeftButtonDown(e);
                //在命令目标上执行命令,或称让命令作用于命令目标
                if (this.CommandTarget!=null)
                {
                    this.Command.Execute(this.CommandTarget);
                }
            }
        }
    
    
    
        
    }
    mainWindow.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MiniView.xaml 的交互逻辑
        /// </summary>
        public partial class MiniView : UserControl,IView
        {
            public MiniView()
            {
                InitializeComponent();
            }
    
            //继承自IView的成员们
            public bool isChanged { get ; set; }
    
            public void SetBinding() { }
            public void Refresh() { }
            public void Save() { }
            //用于清除内容的业务逻辑
            public void Clear()
            {
                this.textBox1.Clear();
                this.textBox2.Clear();
                this.textBox3.Clear();
                this.textBox4.Clear();
            }
           
        }
    }
    miniWindow.cs

    10  深入浅出话资源

    10.2  且”静“且“动”的资源

    DynamicResource:动态资源使用

    StaticResource:静态资源使用

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="450" Width="800">
        <Window.Resources>
            <TextBlock x:Key="res1" Text="海上生明月"/>
            <TextBlock x:Key="res2" Text="海上生明月"/>
        </Window.Resources>
        <StackPanel>
            <Button Margin="5,5,5,0" Content="{StaticResource res1}"/>
            <Button Margin="5,5,5,0" Content="{DynamicResource res2}"/>
            <Button Margin="5,5,5,0" Content="Update" Click="Button_Click"/>
        </StackPanel>
        
        
        
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                //声明命令并使用命令源和目标与之关联
             
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                this.Resources["res1"] = new TextBlock() { Text = "天涯共此时" };
                this.Resources["res2"] = new TextBlock() { Text = "天涯共此时" };
            }
        }
    
       
    
    
    
        
    }
    cs

    10.3  向程序添加二进制资源

    注意:如果想让外部文件编译进目标成为二进制资源,必须在属性窗口把文件的Build Action设置为Resource 一般情况下如果Build Action设置为Resource 则Copy to Output Directory设为Do not copy

    不希望以资源形式使用外部文件,可以啊Build Action 设为None 把Copy to Output Directory 设为Copy always

    10.4  使用Pack URi路径访问二进制资源

    pack://application,,,[/程序集名称;][可选版本;][文件夹名称/]文件名称
    
    [文件夹名称/]文件名称

    11  深入浅出话模板

     11.2  数据的外衣DataTemplate

    需求:有一列汽车数据,这列数据显示在ListBox的条目显示汽车的厂商图标和简要参数,单击某个条目后在窗体的详细内容区域显示汽车的照片和详细参数

    模式1:事件驱动

    <UserControl x:Class="WpfApp4.UserControl2"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApp4"
           >
        <Border BorderBrush="black" BorderThickness="1" CornerRadius="6">
            <StackPanel Margin="5">
                <Image x:Name="imagePhoto" Width="400" Height="250"/>
                <StackPanel Orientation="Horizontal" Margin="5,0">
                    <TextBlock Text="Name:" FontWeight="Bold" FontSize="20"/>
                    <TextBlock x:Name="textBlockName" FontSize="20" Margin="5,0"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" Margin="5,0">
                    <TextBlock Text="Automaker:" FontWeight="Bold" FontSize="20"/>
                    <TextBlock x:Name="textBlockAutomaker" FontSize="20" Margin="5,0"/>
                    <TextBlock Text="Year:" FontWeight="Bold" FontSize="20"/>
                    <TextBlock x:Name="textBlockYear" FontSize="20" Margin="5,0"/>
                    <TextBlock Text="Top Speed:" FontWeight="Bold" FontSize="20"/>
                    <TextBlock x:Name="textBlockTopSpeed" FontSize="20" Margin="5,0"/>
                </StackPanel>
    
            </StackPanel>
    
    
    
        </Border>
    </UserControl>
    usercontr2_xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using static WpfApp4.MainWindow;
    
    namespace WpfApp4
    {
        /// <summary>
        /// UserControl2.xaml 的交互逻辑
        /// </summary>
        public partial class UserControl2 : UserControl
        {
            public UserControl2()
            {
                InitializeComponent();
            }
    
            private Car car;
            public Car Car
            {
                get { return car; }
                set 
                {
                    car = value;
                    this.textBlockName.Text = car.Name;
                    this.textBlockYear.Text = car.Year;
                    this.textBlockTopSpeed.Text = car.TopSpeed;
                    this.textBlockAutomaker.Text = car.Automaker;            
                    string uriStr = string.Format(@"/Images/{0}.png", car.Name);
                    this.imagePhoto.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));
                }
            }
        }
    }
    usercontr2_xaml.cs
    <UserControl x:Class="WpfApp4.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApp4"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <Grid Margin="2">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="imageLogo" Grid.RowSpan="3" Width="64" Height="64"/>
                <StackPanel Margin="5,10">
                    <TextBlock x:Name="textBlockName" FontSize="16" FontWeight="Bold"/>
                    <TextBlock x:Name="textBlockYear" FontSize="14"/>
    
                </StackPanel>
    
            </StackPanel>
        </Grid>
    </UserControl>
    usercontrol1_xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using static WpfApp4.MainWindow;
    
    namespace WpfApp4
    {
        /// <summary>
        /// UserControl2.xaml 的交互逻辑
        /// </summary>
        public partial class UserControl2 : UserControl
        {
            public UserControl2()
            {
                InitializeComponent();
            }
    
            private Car car;
            public Car Car
            {
                get { return car; }
                set 
                {
                    car = value;
                    this.textBlockName.Text = car.Name;
                    this.textBlockYear.Text = car.Year;
                    this.textBlockTopSpeed.Text = car.TopSpeed;
                    this.textBlockAutomaker.Text = car.Automaker;            
                    string uriStr = string.Format(@"/Images/{0}.png", car.Name);
                    this.imagePhoto.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));
                }
            }
        }
    }
    usercontrol1_xaml.cs
    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:prop="clr-namespace:WpfApp4.Properties"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <StackPanel Orientation="Horizontal" Margin="5">
            <local:UserControl2 x:Name="detailView"/>
            <ListBox x:Name="listBoxCars" Width="180" Margin="5,0"
                     SelectionChanged="listBoxCars_SelectionChanged"/>
        </StackPanel>             
    
    
    </Window>
    mainview_xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                InitialCarList();
               
             
            }
    
            //选择变化事件的处理器
            private void listBoxCars_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                UserControl1 view = e.AddedItems[0] as UserControl1;
                if (view!=null)
                {
                    this.detailView.Car = view.Car;
                }
            }
            public class Car
            {
                public string Automaker { get; set; }
                public string Name { get; set; }
                public string Year { get; set; }
                public string TopSpeed { get; set; }
            }
    
            //初始化listBox
            private void InitialCarList()
            {
                List<Car> carList = new List<Car>()
                {
                    new Car(){ Automaker="Lamborghini",Name="Diablo",Year="1990",TopSpeed="340"},
                    new Car(){ Automaker="Lamborghini",Name="Murcielago",Year="2001",TopSpeed="325"},
    
                };
                foreach (Car car in carList)
                {
                    UserControl1 view = new UserControl1();
                    view.Car = car;
                    this.listBoxCars.Items.Add(view);
                }
            }
            
            
    
    
    
        }
    
    
    
       
    
    
    
        
    }
    maniview_xaml.cs

    模式2:数据驱动

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Data;
    using System.Windows.Media.Imaging;
    
    namespace WpfApp4
    {
        //厂商名称转换为Logo图片路径
        public class AutomakerToLogoPathConvert : IValueConverter
        {
            //正向转化
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                string uriStr = string.Format(@"/Logos/{0}.png", (string)value);
                return new BitmapImage(new Uri(uriStr, UriKind.Relative));
            }
            //未被用到
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
        //汽车名称转换为照片路径
        public class NmaeToLogoPathConvert : IValueConverter
        {
            //正向转化
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                string uriStr = string.Format(@"/Images/{0}.png", (string)value);
                return new BitmapImage(new Uri(uriStr, UriKind.Relative));
            }
            //未被用到
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    convert.cs
    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <!--converters-->
            <local:AutomakerToLogoPathConvert x:Key="a21"/>
            <local:NmaeToLogoPathConvert x:Key="n2p"/>
            <!--DataTemplate for Detail View-->
            <DataTemplate x:Key="carDetaiIViewTemplate">
                <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6">
                    <StackPanel Margin="5">
                        <Image Width="400" Height="250"
                                         Source="{Binding Name,Converter={StaticResource n2p}}"/>
                        <StackPanel Orientation="Horizontal" Margin="5">
                            <TextBlock Text="Name" FontWeight="Bold" FontSize="20"/>
                            <TextBlock Text="{Binding Name}" FontSize="20" Margin="5,0"/>
                        </StackPanel>
                        <StackPanel Orientation="Horizontal" Margin="5,0">
                            <TextBlock Text="Automaker" FontWeight="Bold" FontSize="20"/>
                            <TextBlock Text="{Binding Automaker}" FontSize="20" Margin="5,0"/>
                            <TextBlock Text="Year" FontWeight="Bold" FontSize="20"/>
                            <TextBlock Text="{Binding Year}" FontSize="20" Margin="5,0"/>
                            <TextBlock Text="Top Speed" FontWeight="Bold" FontSize="20"/>
                            <TextBlock Text="{Binding TopSpeed}" FontSize="20" Margin="5,0"/>
                        </StackPanel>
                    </StackPanel>
                </Border>
            </DataTemplate>
            <!--DataTemplate for Item View-->
            <DataTemplate x:Key="carListItemViewTemplate">
                <Grid Margin="2">
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Automaker,Converter={StaticResource a21}}"
                               Grid.RowSpan="3" Width="64" Height="64"/>
                        <StackPanel Margin="5,10">
                            <TextBlock Text="{Binding Name}" FontSize="16" FontWeight="Bold"/>
                            <TextBlock Text="{Binding Year}" FontSize="14"/>
                        </StackPanel>
                        
                    </StackPanel>
                 </Grid>
                      
            </DataTemplate>
        </Window.Resources>
        <!--窗体内容-->
        <StackPanel Orientation="Horizontal" Margin="5">
            <UserControl ContentTemplate="{StaticResource  carDetaiIViewTemplate}"
                         Content="{Binding SelectedItem,ElementName=listBoxCars}"/>
            <ListBox x:Name="listBoxCars" Width="180" Margin="5,0"
                     ItemTemplate="{StaticResource carListItemViewTemplate}"/>
    
        </StackPanel>
    </Window>
    mainWindow.xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                InitialCarList();
    
    
    
            }
    
            public class Car
            {
                public string Automaker { get; set; }
                public string Name { get; set; }
                public string Year { get; set; }
                public string TopSpeed { get; set; }
            }
    
            //初始化listBox
            private void InitialCarList()
            {
                List<Car> carList = new List<Car>()
                {
                    new Car(){ Automaker="Lamborghini",Name="Diablo",Year="1990",TopSpeed="340"},
                    new Car(){ Automaker="Lamborghini",Name="Murcielago",Year="2001",TopSpeed="325"},
    
                };
                //填充数据源
                this.listBoxCars.ItemsSource = carList;
            }
    
    
        }
    
    
    }
    
    
    
       
    
    
    
        
    mainWindow.cs

     11.3  控件的外衣ControlTemplate

    11.3.2  ItemsConteol的PanelTemplate

    11.4  DataTemplate与ControlTemplate的关系与应用

    11.4.1  DataTemplate与ControlTemplate的关系

    11.4.2  DataTemplate与ControlTemplate的应用

    把ControlTemplate应用在所有目标上需要借助Style来实现,但Stayle不能标记x:Key例如如下代码

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBox}">
                            <Border x:Name="Bd" SnapsToDevicePixels="True"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="5">
                                <ScrollViewer x:Name="PART_ContentHost"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="Margin" Value="5"/>
                <Setter Property="BorderBrush" Value="black"/>
                <Setter Property="Height" Value="25"/>
            </Style>
        </Window.Resources>
        <StackPanel>
            <TextBox/>
            <TextBox/>
            <TextBox Style="{x:Null}" Margin="5"/>
        </StackPanel>
    </Window>
    xaml

    把DataTemplate应用在某个数据类型伤感的方法市设置DataTemplate的DataType属性,并且DataTemplate作为资源时不能带有x:Key标记

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
        <!--DataTemplate-->
            <DataTemplate DataType="{x:Type local:Unit}"    >
                <Grid>
                    <StackPanel Orientation="Horizontal">
                        <Grid>
                            <Rectangle Stroke="Yellow" Fill="Orange" Width="{Binding price}"/>
                            <TextBlock Text="{Binding Year}"/>
                        </Grid>
                        <TextBlock Text="{Binding price}" Margin="5,0"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
            <!--数据源-->
            <c:ArrayList x:Key="ds">
                <local:Unit Year="2001" price="100"/>
                <local:Unit Year="2002" price="150"/>
                <local:Unit Year="2003" price="180"/>
                <local:Unit Year="2004" price="190"/>
                <local:Unit Year="2005" price="120"/>
                <local:Unit Year="2006" price="130"/>
                <local:Unit Year="2007" price="150"/>
            </c:ArrayList>
        </Window.Resources>
        <StackPanel>
            <ListBox ItemsSource="{StaticResource ds}"></ListBox>
            <ComboBox ItemsSource="{StaticResource ds}" Margin="5"/>
        </StackPanel>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
    
    
            }
    
    
    
        }
        public class Unit
        { 
            public int price { get; set; }
            public string Year { get; set; }
        }
    
    }
    
    
    
       
    
    
    
        
    xaml.cs

    当数据是以XML形式存储时,DataTemplate具有直接把XML数据结点当作目标对象的功能——XML数据中元素名可直接作为DataType,元素的子节点可以使用XPath来访问

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
        <!--DataTemplate-->
            <DataTemplate DataType="Unit"    >
                <Grid>
                    <StackPanel Orientation="Horizontal">
                        <Grid>
                            <Rectangle Stroke="Yellow" Fill="Orange" Width="{Binding XPath=@Price}"/>
                            <TextBlock Text="{Binding XPath=@Year}"/>
                        </Grid>
                        <TextBlock Text="{Binding XPath=@Price}" Margin="5,0"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
            <!--数据源-->
            <XmlDataProvider x:Key="ds" XPath="Units/Unit">
                <x:XData>
                    <Units xmlns="">
                        <Unit Year="2000" Price="100"/>
                        <Unit Year="2001" Price="120"/>
                        <Unit Year="2002" Price="140"/>
                        <Unit Year="2003" Price="160"/>
                        <Unit Year="2004" Price="180"/>
                        <Unit Year="2005" Price="200"/>
                    </Units>
                </x:XData>
            </XmlDataProvider>
        </Window.Resources>
        <StackPanel>
            <ListBox ItemsSource="{Binding Source={StaticResource ds}}"></ListBox>
            <ComboBox ItemsSource="{Binding Source={StaticResource ds}}" Margin="5"/>
        </StackPanel>
    </Window>
    xaml

    使用TreeView显示多层级,不同类型数据

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <!--数据源-->
            <XmlDataProvider x:Key="ds" Source="Data.xml" XPath="Data/Grade"/>
            <!--年级模板-->
            <HierarchicalDataTemplate DataType="Grade" ItemsSource="{Binding XPath=Class}">
                <TextBlock Text="{Binding XPath=@Name}"/>
            </HierarchicalDataTemplate>
            <!--班级模板-->
            <HierarchicalDataTemplate DataType="Class" ItemsSource="{Binding XPath=Group}">
                <RadioButton Content="{Binding XPath=@Name}" GroupName="gn"/>
            </HierarchicalDataTemplate>
            <!--小组模板--> 
            <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding XPath=Student}">
                <CheckBox Content="{Binding XPath=@Name}"/>
            </HierarchicalDataTemplate>
        </Window.Resources>
        <Grid>
            <TreeView Margin="5" ItemsSource="{Binding Source={StaticResource ds}}"/>
        </Grid>
       
    </Window>
    xaml

    同一种数据类型的嵌套结构,只需要设计一个HierachicalDataTemplate就好了,它会自动迭代应用效果

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <!--数据源-->
            <XmlDataProvider x:Key="ds" Source="Data.xml" XPath="Data/Operation"/>
            <!--Operation-->
            <HierarchicalDataTemplate DataType="Operation" ItemsSource="{Binding XPath=Operation}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding XPath=@Name}" Margin="10,0"/>
                    <TextBlock Text="{Binding XPath=@Gesture}" Margin="10,0"/>
                </StackPanel>
    
            </HierarchicalDataTemplate>
        </Window.Resources>
        <Grid MenuItem.Click="Grid_Click">
            <Menu ItemsSource="{Binding Source={StaticResource ds}}"/>
        </Grid>
       
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
    
    
            }
    
            private void Grid_Click(object sender, RoutedEventArgs e)
            {
                MenuItem mi = e.OriginalSource as MenuItem;
                XmlElement xe = mi.Header as XmlElement;
                MessageBox.Show(xe.Attributes["Name"].Value);
            }
        }
    
    
    }
    
    
    
       
    
    
    
        
    xaml.cs
    <?xml version="1.0" encoding="utf-8" ?>
    <Data xmlns="">
        <Operation Name="文件">
            <Operation Name="新建" Gesture="N">            
                    <Operation Name="项目" Gesture="Control+P"/>
                    <Operation Name="网站" Gesture="Control+W"/>
                    <Operation Name="文档" Gesture="Control+D"/>
            </Operation>
            <Operation Name="保存" Gesture="Control+S"/>
            <Operation Name="打印" Gesture="Control+P"/>
            <Operation Name="退出" Gesture="Control+X"/>                
            </Operation>
        <Operation Name="编辑" >
            <Operation Name="拷贝" Gesture="Control+C"/>
            <Operation Name="剪切" Gesture="Control+X"/>
            <Operation Name="粘贴" Gesture="Control+V"/>
        </Operation>
        
    </Data>
    XML

    11.4.3  寻找失落的控件

    寻找由ControlTempate生成的控件

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <ControlTemplate x:Key="cTmp">
                <StackPanel Background="Orange" >
                    <TextBox x:Name="textBox1" Margin="6"/>
                    <TextBox x:Name="textBox2" Margin="6,0"/>
                    <TextBox x:Name="textBox3" Margin="6"/>
                </StackPanel>
            </ControlTemplate>
        </Window.Resources>
        <StackPanel Background="Yellow">
            <UserControl x:Name="uc" Template="{StaticResource cTmp}" Margin="5"/>
            <Button Content="Find by Name" Width="120" Height="30" Click="Button_Click"/>
        </StackPanel>
       
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
    
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                TextBox tb = this.uc.Template.FindName("textBox1", this.uc) as TextBox;
                tb.Text = "Hello WPF";
                StackPanel sp = tb.Parent as StackPanel;
                (sp.Children[1] as TextBox).Text = "Hello ControlTemple";
                (sp.Children[2] as TextBox).Text = "I can find you!";
            }
        }
    
    
    }
    
    
    
       
    
    
    
        
    xaml.cs

    寻找由DataTemplate生成的控件

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
        <!--数据对象-->
            <local:Student x:Key="stu" Id="1" Name="Timothy" Skill="WPF" HasJob="True"/>
            <!--DataTemplate-->
            <DataTemplate x:Key="stuDT">
                <Border BorderBrush="Orange" BorderThickness="2" CornerRadius="5">
                    <StackPanel>
                        <TextBlock Text="{Binding Id}" Margin="5"/>
                        <TextBlock x:Name="textBlockName" Text="{Binding Name}" Margin="5"/>
                        <TextBlock Text="{Binding Skill}" Margin="5"/>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </Window.Resources>
        <!--主体布局-->
        <StackPanel>
            <ContentPresenter x:Name="cp" Content="{StaticResource stu}"
                              ContentTemplate="{StaticResource stuDT}" Margin="5"/>
            <Button Content="Find" Margin="5,0" Click="Button_Click"/>
        </StackPanel>
       
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                TextBlock tb = this.cp.ContentTemplate.FindName("textBlockName", this.cp) as TextBlock;
                MessageBox.Show(tb.Text);
    
                //Student stu = this.cp.Content as Student;
                //MessageBox.Show(stu.Name);
            }
        }
    
        public class Student
        { 
            public int Id { get; set; }
            public string Name { get; set; }
            public string Skill { get; set; }
            public bool HasJob { get; set; }
        }
    
    }
    
    
    
       
    
    
    
        
    xaml.cs
    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
    <!--数据集合-->
            <c:ArrayList x:Key="stuList">
                <local:Student Id="1" Name="Timoty" Skill="WPF" HasJob="True"/>
                <local:Student Id="2" Name="Timoty1" Skill="WPF1" HasJob="False"/>
                <local:Student Id="3" Name="Timoty2" Skill="WPF2" HasJob="True"/>
                <local:Student Id="4" Name="Timoty3" Skill="WPF3" HasJob="False"/>
                <local:Student Id="5" Name="Timoty4" Skill="WPF4" HasJob="True"/>
            </c:ArrayList>
            <!--DataTemplate-->
            <DataTemplate x:Key="nameDT">
                <TextBox x:Name="textBoxName" Text="{Binding Name}" GotFocus="textBoxName_GotFocus"/>
            </DataTemplate>
            <DataTemplate x:Key="skillDT">
                <TextBox x:Name="textBoxSkill" Text="{Binding Skill}"/>
            </DataTemplate>
            <DataTemplate x:Key="hjDT">
                <CheckBox x:Name="checkBoxJob" IsChecked="{Binding HasJob}"/>
            </DataTemplate>
        </Window.Resources>
    <!--主体布局-->
        <Grid Margin="5">
            <ListView x:Name="listViewStudetn" ItemsSource="{StaticResource stuList}">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}"/>
                        <GridViewColumn Header="姓名" CellTemplate="{StaticResource nameDT}"/>
                        <GridViewColumn Header="技术" CellTemplate="{StaticResource skillDT}"/>
                        <GridViewColumn Header="已工作" CellTemplate="{StaticResource hjDT}" />
                    </GridView>
                </ListView.View>
                
            </ListView>
            
        </Grid>
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void textBoxName_GotFocus(object sender, RoutedEventArgs e)
            {
                //访问业务逻辑数据
                TextBox tb = e.OriginalSource as TextBox;   //获取事件发起的源头
                ContentPresenter cp = tb.TemplatedParent as ContentPresenter;//获取模板目标
                Student stu = cp.Content as Student;//获取业务逻辑
                this.listViewStudetn.SelectedItem = stu;//设置ListView的选中项
    
                //访问界面元素
                ListViewItem lvi = this.listViewStudetn.ItemContainerGenerator.ContainerFromItem(stu) as ListViewItem;
                CheckBox chb = this.FindVisualChild<CheckBox>(lvi);
                MessageBox.Show(chb.Name);
    
            }
    
    
            private ChildType FindVisualChild<ChildType>(DependencyObject obj)
                where ChildType : DependencyObject
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                    if (child != null && child is ChildType)
                    {
                        return child as ChildType;
                    }
                    else
                    {
                        ChildType childOfChiild = FindVisualChild<ChildType>(child);
                        if (childOfChiild != null)
                        {
                            return childOfChiild;
                        }
                    }
                }
                return null;
            }
        }
    
    
        public class Student
        { 
            public int Id { get; set; }
            public string Name { get; set; }
            public string Skill { get; set; }
            public bool HasJob { get; set; }
        }
    
    }
    
    
    
       
    
    
    
        
    xaml.cs

    11.5  深入浅出话Style  

    11.5.1  styel中的setter

    11.5.2  styel中的Trigger

    1.基本的Trigger

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <Style TargetType="CheckBox" >
                <Style.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Trigger.Setters >
                            <Setter Property="FontSize" Value="20"/>
                            <Setter Property="Foreground"  Value="Orange"/>
                        </Trigger.Setters>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <StackPanel>
            <CheckBox Content="悄悄的我走了" Margin="5"/>
            <CheckBox Content="正如我悄悄的来" Margin="5"/>
            <CheckBox Content="我挥一挥衣袖" Margin="5"/>
            <CheckBox Content="不带走一片云彩" Margin="5"/>
        </StackPanel>
    </Window>
    xaml

    2.MuitiTrigger

    多个条件满足才会触发

    3.由数据触发的DataTrigger

    长度小于6 边框显示为红色

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <local:L2BConvert x:Key="cvtr"/>
            <Style TargetType="TextBox">
                <Style.Triggers>
                    <DataTrigger  
                        Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text.Length, 
                        Converter={StaticResource cvtr}}" Value="false">
                        <Setter Property="BorderBrush" Value="Red"/>
                        <Setter Property="BorderThickness" Value="1"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <StackPanel>
            <TextBox Margin="5"/>
            <TextBox Margin="5"/>
            <TextBox Margin="5"/>
        </StackPanel>
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
    
        }
    
        public class L2BConvert : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                int textLengrh = (int)value;
                return textLengrh > 6 ? true : false;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    
    
    
       
    
    
    
        
    xaml.cs

    4.多数据条件触发的MultiDataTrigger

     需求:用户界面上使用ListBox显示了一列Student数据,当数据同时满足Id为2、Name为Tom时,条目高亮。

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <Style TargetType="ListBoxItem">
                <!--使用Style设置DataTemplate-->
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Id}" Width="60"/>
                                <TextBlock Text="{Binding Name}" Width="120"/>
                                <TextBlock Text="{Binding Age}" Width="60"/>
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
                <!--MultiDataTrigger-->
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Path=Id}" Value="2"/>
                            <Condition Binding="{Binding Path=Name}" Value="Tom"/>
                        </MultiDataTrigger.Conditions>
                        <MultiDataTrigger.Setters>
                            <Setter Property="Background" Value="Orange"/>
                        </MultiDataTrigger.Setters>
                    </MultiDataTrigger>
                </Style.Triggers>
                
            </Style>
        </Window.Resources>
        <StackPanel>
            <ListBox x:Name="listBoxStudet" Margin="5"/>
        </StackPanel>
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
                //初始化listbox
                List<Student> stuList = new List<Student>()
                {
                    new Student(){Id=1,Name="Tom2",Age=10},
                    new Student(){Id=2,Name="Tom",Age=11},
                    new Student(){Id=3,Name="Tom3",Age=11}
    
                };
                this.listBoxStudet.ItemsSource = stuList;
            }
    
    
        }
        public class Student
        { 
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age{ get; set; }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs

    5.由事件触发的EventTrigger

    又事件触发触发后是执行一段动画

    下面例子中创建了一个针对Button的Style,这个Syle包含两个EventTrigger,一个由MouseEvnet事件触发,另一个由MouseLeave事件触发.

    鼠标进入,button变大,鼠标离开,button变小

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
        <Window.Resources>
            <Style TargetType="Button">
                <Style.Triggers>
                    <!--鼠标进入-->
                    <EventTrigger RoutedEvent="MouseEnter">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Width" />
                                <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Height" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <!--鼠标离开-->
                    <EventTrigger RoutedEvent="MouseLeave">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation  Duration="0:0:0.2" Storyboard.TargetProperty="Width" />
                                <DoubleAnimation  Duration="0:0:0.2" Storyboard.TargetProperty="Height" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <Canvas>
            <Button Width="40" Height="40" Content="OK"/>
        </Canvas>
    
    
    </Window>
    xaml

     

    12.4  动画

    12.4.1  简单动画

    1.简单线性动画

    变化时间Duration:必须指定

    变化终点To:如果没有指定,程序将采用上一次动画的终点或默认值。

    变化幅度By:如果同时指定了变化终点,变化幅度将被忽略。

    变化起点From:如果没有指定变化起点则以变化目标的当前值为起点。

    需求:用户界面上有Button按钮,每次点击Button时,会改变Button的显示位置

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
    
        <Grid>
            <Button Content="Move!" HorizontalAlignment="Left" VerticalAlignment="Top"
                    Width="60" Height="60" Click="Button_Click">
                <Button.RenderTransform>
                    <TranslateTransform x:Name="tt" X="0" Y="0"/>
                </Button.RenderTransform>
                
            </Button>
        </Grid>
    
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Windows.Media.Animation;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DoubleAnimation daX = new DoubleAnimation();
                DoubleAnimation daY = new DoubleAnimation();
    
                //指定起点
                //daX.From = 0D;
                //daY.From = 0D;
                //指定幅度
                daX.By = 100D;
                daY.By = 100D;
                ////指定终点
                //Random r = new Random();
                //daX.To = r.NextDouble() * 300;
                //daY.To = r.NextDouble() * 300;
                //指定时长
                Duration duration = new Duration(TimeSpan.FromMilliseconds(30));
                daX.Duration = duration;
                daY.Duration = duration;
                //动画主体 是TranslateTransform变形非Button
                this.tt.BeginAnimation(TranslateTransform.XProperty, daX);
                this.tt.BeginAnimation(TranslateTransform.YProperty, daY);
    
            }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs

    2.  高级动画控制

    AccelerationRadion  加速速率,介于0.0和1.0之间,与Deceleration之和不大于1.0     模拟汽车启动

    DecelerationRadion  减速速率,介于0.0和1.0之间,与Acceleration之和不大于1.0     模拟汽车刹车

    SpeedRadion       动画实际播放与正常速度比值                  快进播放、慢动作

    AutoReverse     是否以相反动画方式从终止值返回起始值             倒退播放

    RepeatBehavior        动画的重复行为,取0不播放,使用double类型值可控制循环次数,

               取RepeatBehavior.Forever为永远循环              循环播放

    BeginTime      正式开始播放前的等待时间                   多个动画之间的协同  

    EasingFunction      缓冲式渐变                          乒乓球跳效果

    案例:乒乓球弹跳式的效果

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
    
        <Grid>
            <Button Content="Move!" HorizontalAlignment="Left" VerticalAlignment="Top"
                    Width="60" Height="60" Click="Button_Click">
                <Button.RenderTransform>
                    <TranslateTransform x:Name="tt" X="0" Y="0"/>
                </Button.RenderTransform>
                
            </Button>
        </Grid>
    
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Windows.Media.Animation;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DoubleAnimation daX = new DoubleAnimation();
                DoubleAnimation daY = new DoubleAnimation();
    
                //指定起点
                BounceEase be = new BounceEase();
                be.Bounces = 3;//弹跳3次
                be.Bounciness = 3;//弹性程度,值越大反弹越低
                daY.EasingFunction = be;
                //指定终点
    
                daX.To = 300;
                daY.To = 300;
    
                //指定时长
                Duration duration = new Duration(TimeSpan.FromMilliseconds(2000));
                daX.Duration = duration;
                daY.Duration = duration;
    
                //动画主体 是TranslateTransform变形非Button
                this.tt.BeginAnimation(TranslateTransform.XProperty, daX);
                this.tt.BeginAnimation(TranslateTransform.YProperty, daY);
    
            }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs

    3.  关键帧动画

    关键帧动画允许程序员为一段动画设置几个”里程碑“ 动画执行到里程碑所在的关键的时间点时,被动画所控制的属性值也必须达到设定的值。

    案例:button按照z字型动作

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
    
        <Grid>
            <Button Content="Move!" HorizontalAlignment="Left" VerticalAlignment="Top"
                    Width="60" Height="60" Click="Button_Click">
                <Button.RenderTransform>
                    <TranslateTransform x:Name="tt" X="0" Y="0"/>
                </Button.RenderTransform>
                
            </Button>
        </Grid>
    
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Windows.Media.Animation;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DoubleAnimationUsingKeyFrames daX = new DoubleAnimationUsingKeyFrames();
                DoubleAnimationUsingKeyFrames daY = new DoubleAnimationUsingKeyFrames();
    
                //设置动画总时长
                daX.Duration = new Duration(TimeSpan.FromMilliseconds(900));
                daY.Duration = new Duration(TimeSpan.FromMilliseconds(900));
    
                //创建、添加关键帧
                LinearDoubleKeyFrame x_kf_1 = new LinearDoubleKeyFrame();
                LinearDoubleKeyFrame x_kf_2 = new LinearDoubleKeyFrame();
                LinearDoubleKeyFrame x_kf_3 = new LinearDoubleKeyFrame();
    
                x_kf_1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                x_kf_1.Value = 200;
                x_kf_2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(600));
                x_kf_2.Value = 0;
                x_kf_3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(900));
                x_kf_3.Value = 200;
    
                daX.KeyFrames.Add(x_kf_1);
                daX.KeyFrames.Add(x_kf_2);
                daX.KeyFrames.Add(x_kf_3);
    
    
                LinearDoubleKeyFrame y_kf_1 = new LinearDoubleKeyFrame();
                LinearDoubleKeyFrame y_kf_2 = new LinearDoubleKeyFrame();
                LinearDoubleKeyFrame y_kf_3 = new LinearDoubleKeyFrame();
    
                y_kf_1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                y_kf_1.Value = 0;
                y_kf_2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(600));
                y_kf_2.Value = 180;
                y_kf_3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(900));
                y_kf_3.Value = 180;
    
                daY.KeyFrames.Add(y_kf_1);
                daY.KeyFrames.Add(y_kf_2);
                daY.KeyFrames.Add(y_kf_3);
    
    
    
             
                //动画主体 是TranslateTransform变形非Button
                this.tt.BeginAnimation(TranslateTransform.XProperty, daX);
                this.tt.BeginAnimation(TranslateTransform.YProperty, daY);
    
            }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs

    4.  特殊的关键帧

    DoubleAnimationUsingFrames的KeyFrames属性的数据类型时DoubleKeyFrameCollection,此类集合可接收的元素类型为DoubleKeyFrame。DoubleKeyFrame是一个抽象类

    DoubleKeyFrame的所有派生类如下

     LinearDoubleKeyFrame:线性变化关键帧,目标属性值的变化是直线的、均匀的,即变化的速率不变。

    DiscreteDoubleKeyFrame:不连续变化关键帧,目标属性值是跳跃性、跃迁性的。

    SplineDoubleKeyFrame:样条函数式变化关键帧,目标属性值的变化速率式一条贝塞尔曲线。

    EasingDoubleKeyFrame:缓冲样式变化关键帧,目标属性值以某种缓冲形式变化。

     SplineDoubleKeyFrame案例

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
    
        <Grid>
            <Button Content="Move!" HorizontalAlignment="Left" VerticalAlignment="Top"
                    Width="60" Height="60" Click="Button_Click">
                <Button.RenderTransform>
                    <TranslateTransform x:Name="tt" X="0" Y="0"/>
                </Button.RenderTransform>
                
            </Button>
        </Grid>
    
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Windows.Media.Animation;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                //创建动画
                DoubleAnimationUsingKeyFrames dakX = new DoubleAnimationUsingKeyFrames();
                dakX.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
                //创建、添加关键帧
                SplineDoubleKeyFrame kf = new SplineDoubleKeyFrame();
                kf.KeyTime = KeyTime.FromPercent(1);
                kf.Value = 400;
                KeySpline ks = new KeySpline();
                ks.ControlPoint1 = new Point(0, 1);
                ks.ControlPoint2 = new Point(1, 0);
                kf.KeySpline = ks;
                dakX.KeyFrames.Add(kf);
    
                //执行动画
                this.tt.BeginAnimation(TranslateTransform.XProperty, dakX);
    
      
    
            }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs

     5.路径动画

    让目标对象沿着给定的路径移动,使用DoubleAnimationUsingPath类,DoubleAnimationUsingPath类需要一个PathGeometry来指明移动路径,Pathgeometry的数据信息可以用AML的Path语法书写。

    PathGeometry的重要属性式Source,Source数据类型的取值是PathAnimationSource枚举,

    枚举取X时,意味着这个动画关注的是曲线上每一点横坐标的变化。

    枚举取Y时,意味着这个动画关注的是曲线上每一点纵坐标的变化。

    枚举取Angle时,意味着这个动画关注的是曲线上每一点切线方向的变化。

    案例:让一个Button沿着一条贝塞尔曲线做波浪运动

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
    
        <Grid x:Name="LayoutRoot">
            <Grid.Resources>
                <!--移动路径-->
                <PathGeometry x:Key="movingPath" Figures="M 0,150 C300,-100 300,400 600,120"/>
            </Grid.Resources>
            <Button Content="Move" HorizontalAlignment="Left" VerticalAlignment="Top"  Width="80" Height="80" Click="Button_Click">
                <Button.RenderTransform>
                    <TranslateTransform x:Name="tt" X="0" Y="0"/>
                </Button.RenderTransform>
                
            </Button>
        </Grid>
    
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Windows.Media.Animation;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                //从XAMl代码中获取移动路径数据
                PathGeometry pg = this.LayoutRoot.FindResource("movingPath") as PathGeometry;
                Duration duration = new Duration(TimeSpan.FromMilliseconds(600));
                //创建动画
                DoubleAnimationUsingPath dapX = new DoubleAnimationUsingPath();
                dapX.PathGeometry = pg;
                dapX.Source = PathAnimationSource.X;
                dapX.Duration = duration;
    
                DoubleAnimationUsingPath dapY = new DoubleAnimationUsingPath();
                dapY.PathGeometry = pg;
                dapY.Source = PathAnimationSource.Y;
                dapY.Duration = duration;
    
                //自动返回、永远循环
                dapX.AutoReverse = true;
                dapX.RepeatBehavior = RepeatBehavior.Forever;
                dapY.AutoReverse = true;
                dapY.RepeatBehavior = RepeatBehavior.Forever;
    
                //执行动画
                this.tt.BeginAnimation(TranslateTransform.XProperty, dapX);
                this.tt.BeginAnimation(TranslateTransform.YProperty, dapY);
    
            }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs

    12.4.2  场景

    场景(StoryBoard)并行执行的一组动画

    案例

    <Window x:Class="WpfApp4.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:WpfApp4"   Title="123t"
            xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
            mc:Ignorable="d"
            x:Name="window_1"  Height="350" Width="623">
    
        <Grid Margin="6">
            <!--布局控制-->
            <Grid.RowDefinitions>
                <RowDefinition Height="38"/>
                <RowDefinition Height="38"/>
                <RowDefinition Height="38"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition  Width="60"/>
            </Grid.ColumnDefinitions>
            <!--跑道红-->
            <Border BorderBrush="Gray" BorderThickness="1" Grid.Row="0">
                <Ellipse x:Name="ballR" Height="36" Width="36" Fill="Red" HorizontalAlignment="Left">
                    <Ellipse.RenderTransform>
                        <TranslateTransform x:Name="ttR"/>
                    </Ellipse.RenderTransform>
                </Ellipse>
            </Border>
            <!--跑道绿-->
            <Border BorderBrush="Gray" BorderThickness="1,0,1,1" Grid.Row="1">
                <Ellipse x:Name="ballG" Height="36" Width="36" Fill="LawnGreen"  HorizontalAlignment="Left">
                    <Ellipse.RenderTransform>
                        <TranslateTransform x:Name="ttG"/>
                    </Ellipse.RenderTransform>
                </Ellipse>
            </Border>
            <!--跑道蓝-->
            <Border BorderBrush="Gray" BorderThickness="1,0,1,1" Grid.Row="2">
                <Ellipse x:Name="ballB" Height="36" Width="36" Fill="Blue"  HorizontalAlignment="Left">
                    <Ellipse.RenderTransform>
                        <TranslateTransform x:Name="ttB"/>
                    </Ellipse.RenderTransform>
                </Ellipse>
            </Border>
            <!--按钮-->
            <Button Content="Go!" Grid.Column="1" Grid.RowSpan="3" Click="Button_Click"/>
        </Grid>
    
    
    </Window>
    xaml
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.ComponentModel;//使用INotifyPropertyChanged
    using System.Data;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using System.Windows.Media.Animation;
    
    namespace WpfApp4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Duration duration = new Duration(TimeSpan.FromMilliseconds(600));
                //红球匀速移动
                DoubleAnimation daRx = new DoubleAnimation();
                daRx.Duration = duration;
                daRx.To = 400;
                //绿球变速运动
                DoubleAnimationUsingKeyFrames dakGx = new DoubleAnimationUsingKeyFrames();
                dakGx.Duration = duration;
                SplineDoubleKeyFrame kfG = new SplineDoubleKeyFrame(400, KeyTime.FromPercent(1.0));
                kfG.KeySpline = new KeySpline(1, 0, 0, 1);
                dakGx.KeyFrames.Add(kfG);
                //蓝球变速运动
                DoubleAnimationUsingKeyFrames dakBx = new DoubleAnimationUsingKeyFrames();
                dakBx.Duration = duration;
                SplineDoubleKeyFrame kfB = new SplineDoubleKeyFrame(400, KeyTime.FromPercent(1.0));
                kfB.KeySpline = new KeySpline(0, 1, 1, 0);
                dakBx.KeyFrames.Add(kfB);
                //创建场景
                Storyboard storyboard = new Storyboard();
    
                Storyboard.SetTargetName(daRx, "ttR");
                Storyboard.SetTargetProperty(daRx, new PropertyPath(TranslateTransform.XProperty));
    
                Storyboard.SetTargetName(dakGx, "ttG");
                Storyboard.SetTargetProperty(dakGx, new PropertyPath(TranslateTransform.XProperty));
    
                Storyboard.SetTargetName(dakBx, "ttB");
                Storyboard.SetTargetProperty(dakBx, new PropertyPath(TranslateTransform.XProperty));
    
                storyboard.Duration = duration;
                storyboard.Children.Add(daRx);
                storyboard.Children.Add(dakGx);
                storyboard.Children.Add(dakBx);
    
                storyboard.Begin(this);
                storyboard.Completed += (a,b) =>{ MessageBox.Show(ttG.X.ToString());};
                
            }
        }
       
    }
    
    
    
       
    
    
    
        
    xaml.cs
  • 相关阅读:
    RPC实战与核心原理之负载均衡
    RPC实战与核心原理之动态代理了
    RPC实战与核心原理之网络通信
    RPC实战与核心原理之路由策略
    Spring aop自定义注解
    concurrentmap
    索引使用
    第三章—Java NIO编程:(4)Channel 通道
    第一章—Netty 介绍与应用:(1)Netty 介绍与应用场景
    第二章—Java BIO 编程:(1)I/O 模型
  • 原文地址:https://www.cnblogs.com/suwencjp/p/15628071.html
Copyright © 2020-2023  润新知