zoukankan      html  css  js  c++  java
  • 8天入门wpf—— 第八天 最后的补充

        从这一篇往前看,其实wpf中还有很多东西没有讲到,不过我的原则还是将比较常用的知识点过一遍,如果大家熟悉了这些知识,基本功

    也就打的差不多了,后续可以等待老邓的wpf细说系列,这里我先顶老邓一下。

    一:用户控件(UserControl)

          对于用户控件的认识,我想大家还是很熟悉的,因为这玩意我们在webform或者在mvc中用的可多了,我们看看wpf中怎么使用,首先

    我们要知道"用户控件“继承自UserControl,而UserControl继承自ContentControl,也就是上上一篇说的”内容控件”。

    第一步:在vs中的添加项中找到一个“用户控件WPF”,点击添加即可。

    第二步:我们发现其实UserControl和Window是一个层次上的,都有xaml和cs文件,然后我们在xaml中拖几个控件。

     1 <UserControl x:Class="WpfApplication8.AddProduct"
     2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     6              mc:Ignorable="d" 
     7              d:DesignHeight="200" d:DesignWidth="300">
     8     <Grid Height="171" Width="262">
     9         <TextBlock Height="20" HorizontalAlignment="Left" Margin="28,57,0,0" Name="textBlock1" Text="名称:" VerticalAlignment="Top" Width="42" />
    10         <TextBlock Height="20" HorizontalAlignment="Left" Margin="28,92,0,0" Name="textBlock2" Text="价格:" VerticalAlignment="Top" Width="42" />
    11         <TextBox Height="23" HorizontalAlignment="Left" Margin="76,54,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    12         <TextBox Height="23" HorizontalAlignment="Left" Margin="76,92,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
    13     </Grid>
    14 </UserControl>

    第三步:我们在MainWindow中引用,跟webform中使用套路一模一样,最后也就ok了。

    1 <Window x:Class="WpfApplication8.MainWindow"
    2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4         xmlns:local="clr-namespace:WpfApplication8"
    5         Title="MainWindow" Height="350" Width="525">
    6     <Grid>
    7         <local:AddProduct x:Name="test"/>
    8     </Grid>
    9 </Window>

    二:资源文件

         先前文章我也说过,资源就类似于webform中的css,但是实际应用中,css都是一个个单独的文件来实现内容与样式的分离,当然

    wpf中也主张这么做。

    第一步:vs中新建项 -> 资源字典->点击确定

    第二步:这里我就将默认生成的Dictionary1.xaml放在解决方案的Style文件夹下,然后我们写上一段简单的style。

    1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    2                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    3     <Style x:Key="backColor" TargetType="{x:Type Button}">
    4         <Setter Property="Background" Value="Red"/>
    5     </Style>
    6 </ResourceDictionary>

    第三步:在Resources上引用,指定资源文件路径,跟webform中的css文件引用一样一样的。

     1 <Window x:Class="WpfApplication9.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="350" Width="525">
     5     <Window.Resources>
     6         <!-- 引用外部资源文件 -->
     7         <ResourceDictionary>
     8             <ResourceDictionary.MergedDictionaries>
     9                 <ResourceDictionary Source="/Style/Dictionary1.xaml"/>
    10             </ResourceDictionary.MergedDictionaries>
    11         </ResourceDictionary>
    12     </Window.Resources>
    13     <Grid>
    14         <Button Content="Button" Style="{StaticResource ResourceKey=backColor}" Height="23" HorizontalAlignment="Left" Margin="104,58,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    15     </Grid>
    16 </Window>

    三:了解wpf中Window的生命周期

       了解生命周期,可以让我们更好的控制生命周期内各个阶段发生的行为,具体怎么灵活运用,得要看大家灵活发挥了。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Windows;
     6 using System.Windows.Controls;
     7 using System.Windows.Data;
     8 using System.Windows.Documents;
     9 using System.Windows.Input;
    10 using System.Windows.Media;
    11 using System.Windows.Media.Imaging;
    12 using System.Windows.Navigation;
    13 using System.Windows.Shapes;
    14 using System.Diagnostics;
    15 
    16 namespace WpfApplication10
    17 {
    18     /// <summary>
    19     /// MainWindow.xaml 的交互逻辑
    20     /// </summary>
    21     public partial class MainWindow : Window
    22     {
    23         public MainWindow()
    24         {
    25             InitializeComponent();
    26 
    27             //初始化
    28             this.Initialized += (sender, e) =>
    29             {
    30                 Debug.WriteLine("窗体初始化完成 Initialized");
    31             };
    32 
    33             //激活
    34             this.Activated += (sender, e) =>
    35             {
    36                 Debug.WriteLine("窗体被激活 Activated");
    37             };
    38 
    39             //加载
    40             this.Loaded += (sender, e) =>
    41             {
    42                 Debug.WriteLine("窗体加载完成 Loaded");
    43             };
    44 
    45             //呈现内容
    46             this.ContentRendered += (sender, e) =>
    47             {
    48                 Debug.WriteLine("呈现内容 ContentRendered");
    49             };
    50 
    51             //失活
    52             this.Deactivated += (sender, e) =>
    53             {
    54                 Debug.WriteLine("窗体被失活 Deactivated");
    55             };
    56 
    57             //窗体获取输入焦点
    58             this.GotFocus += (sender, e) =>
    59             {
    60                 Debug.WriteLine("窗体获取输入焦点 GotFocus");
    61             };
    62 
    63             //窗体失去输入焦点
    64             this.LostFocus += (sender, e) =>
    65             {
    66                 Debug.WriteLine("窗体失去输入焦点 LostFocus");
    67             };
    68 
    69             //键盘获取输入焦点
    70             this.GotKeyboardFocus += (sender, e) =>
    71             {
    72                 Debug.WriteLine("键盘获取输入焦点 GotKeyboardFocus");
    73             };
    74 
    75             //键盘失去输入焦点
    76             this.LostKeyboardFocus += (sender, e) =>
    77             {
    78                 Debug.WriteLine("键盘失去输入焦点 LostKeyboardFocus");
    79             };
    80 
    81             //正在关闭
    82             this.Closing += (sender, e) =>
    83             {
    84                 Debug.WriteLine("窗体正在关闭 Closeing");
    85             };
    86 
    87             //关闭
    88             this.Closed += (sender, e) =>
    89             {
    90                 Debug.WriteLine("窗体正在关闭 Closed");
    91             };
    92 
    93         }
    94     }
    95 }

    从窗体的开启到关闭,我们可以在“输出窗口”中看到如下的事件发生顺序流。

    四:属性更改通知(INotifyPropertyChanged)

         我们在开发webform中,如果删除GridView里面的一行,我们的作法肯定就是在数据库中删除掉选定的记录然后重新绑定GridView控件

    来实现我们的需求,注意,这里有“重新绑定”一词,但是在wpf中有一个突破,前一篇文章我也提到过wpf中的ObservableCollection<T>,

    MSDN中说,在添加项,移除项时此集合通知控件,我们知道对一个集合的操作是CURD,但是恰恰没有Update的时候提供集合通知,也就

    是说当我Update的时候,虽然"集合内容“已被修改,但是"控件“却没有实现同步更新,怎么办呢?INotifyPropertyChanged提供了解决方案。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Windows;
     6 using System.Windows.Controls;
     7 using System.Windows.Data;
     8 using System.Windows.Documents;
     9 using System.Windows.Input;
    10 using System.Windows.Media;
    11 using System.Windows.Media.Imaging;
    12 using System.Windows.Navigation;
    13 using System.Windows.Shapes;
    14 using System.Collections.ObjectModel;
    15 using System.Windows.Controls.Primitives;
    16 using System.ComponentModel;
    17 
    18 namespace ListViewDemo
    19 {
    20     /// <summary>
    21     /// MainWindow.xaml 的交互逻辑
    22     /// </summary>
    23     public partial class MainWindow : Window
    24     {
    25         private ObservableCollection<Person> personList = new ObservableCollection<Person>();
    26 
    27         public MainWindow()
    28         {
    29             InitializeComponent();
    30 
    31             personList.Add(new Person() { Name = "一线码农", Age = 24 });
    32 
    33             personList.Add(new Person() { Name = "XXX", Age = 21 });
    34 
    35             listview1.ItemsSource = personList;
    36         }
    37 
    38         private void Button_Click(object sender, RoutedEventArgs e)
    39         {
    40             var first = personList.FirstOrDefault();
    41 
    42             first.Name = textBox1.Text;
    43         }
    44     }
    45 
    46     public class Person : INotifyPropertyChanged
    47     {
    48         public string name;
    49 
    50         public string Name
    51         {
    52             get
    53             {
    54                 return name;
    55             }
    56             set
    57             {
    58                 name = value;
    59                 NotifyPropertyChange("Name");
    60             }
    61         }
    62 
    63         public int age;
    64 
    65         public int Age
    66         {
    67             get
    68             {
    69                 return age;
    70             }
    71             set
    72             {
    73                 age = value;
    74                 NotifyPropertyChange("Age");
    75             }
    76         }
    77 
    78         public event PropertyChangedEventHandler PropertyChanged;
    79 
    80         private void NotifyPropertyChange(string propertyName)
    81         {
    82             if (PropertyChanged != null)
    83                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    84         }
    85     }
    86 }
     1 <Window x:Class="ListViewDemo.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="350" Width="525">
     5     <Grid>
     6         <ListView x:Name="listview1">
     7             <ListView.View>
     8                 <GridView>
     9                     <GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Path=Name}"/>
    10                     <GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Path=Age}"/>
    11                 </GridView>
    12             </ListView.View>
    13         </ListView>
    14         <Button Content="更改名字" Click="Button_Click" Margin="315,174,35,103" />
    15         <TextBox Height="23" HorizontalAlignment="Left" Margin="162,180,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    16     </Grid>
    17 </Window>

    我们只要输入名字,然后点击”button按钮”,最后ListView同步更新了,是不是很神奇的说。

    五:依赖属性

        依赖属性是wpf中独有的一种属性,前面文章中或许我们发现WPF的类定义中满是这些玩意,比如我们看一个TextBlock。

    这些Property为后缀的都是叫做依赖属性,不过依赖属性这些东西深究起来内容还是比较多的,不过我还是讲究应用方面,有时候我们

    可能有这样的需求,就是希望能在TextBlock上显示当前时间,这时我们就可以扩展TextBlock,在其中增加一个TimeProperty的依赖

    属性来显示当前时间。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Windows;
     6 using System.Windows.Controls;
     7 using System.Windows.Data;
     8 using System.Windows.Documents;
     9 using System.Windows.Input;
    10 using System.Windows.Media;
    11 using System.Windows.Media.Imaging;
    12 using System.Windows.Navigation;
    13 using System.Windows.Shapes;
    14 
    15 namespace WpfApplication12
    16 {
    17     /// <summary>
    18     /// MainWindow.xaml 的交互逻辑
    19     /// </summary>
    20     public partial class MainWindow : Window
    21     {
    22         public MainWindow()
    23         {
    24             InitializeComponent();
    25         }
    26     }
    27 
    28     public class CustomTextBlock : TextBlock
    29     {
    30         //自定义一个依赖项属性
    31         public static DependencyProperty TimeProperty = DependencyProperty.Register("Timer", typeof(DateTime),
    32                                                        typeof(CustomTextBlock),
    33                                                        new PropertyMetadata(DateTime.Now, OnTimerPropertyChanged),
    34                                                        ValidateTimeValue);
    35         /// <summary>
    36         /// 对依赖属性进行设置值
    37         /// </summary>
    38         public DateTime Time
    39         {
    40             get
    41             {
    42                 //获取当前属性值 
    43                 return (DateTime)GetValue(TimeProperty);
    44             }
    45             set
    46             {
    47                 //给当前的属性赋值
    48                 SetValue(TimeProperty, value);
    49             }
    50         }
    51 
    52 
    53         static void OnTimerPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    54         {
    55 
    56         }
    57 
    58         static bool ValidateTimeValue(object obj)
    59         {
    60             DateTime dt = (DateTime)obj;
    61 
    62             if (dt.Year > 1990 && dt.Year < 2200)
    63                 return true;
    64             return false;
    65         }
    66 
    67     }
    68 }
    1 <Window x:Class="WpfApplication12.MainWindow"
    2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4         xmlns:local="clr-namespace:WpfApplication12"
    5         Title="MainWindow" Height="350" Width="525">
    6     <Grid>
    7         <local:CustomTextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Timer}"/>
    8     </Grid>
    9 </Window>

    最后感谢一直关注此系列的朋友,希望你们有一丝收获。

  • 相关阅读:
    CentOS7搭建SFTP服务
    MySQL主从异常恢复
    MySQL主从复制配置
    Docker安装MySQL8.0
    CentOS7安装JDK1.8
    RabbitMQ死信队列
    RabbitMQ重试机制
    RabbitMQ消息可靠性传输
    TCP/IP的Socket编程
    c#网络编程使用tcpListener和tcpClient
  • 原文地址:https://www.cnblogs.com/huangxincheng/p/2592537.html
Copyright © 2011-2022 走看看