• 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>

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

  • 相关阅读:
    linux 解压tgz 文件指令
    shell 脚本没有执行权限 报错 bash: ./myshell.sh: Permission denied
    linux 启动solr 报错 Your Max Processes Limit is currently 31202. It should be set to 65000 to avoid operational disruption.
    远程查询批量导入数据
    修改 MZTreeView 赋权节点父节点选中子节点自动选中的问题
    关于乱码的问题解决记录
    我的网站优化之路
    对设计及重构的一点反思
    我的五年岁月
    奔三的路上
  • 原文地址:https://www.cnblogs.com/huangxincheng/p/2592537.html
Copyright © 2020-2023  润新知