加载中...

第八天 最后的补充


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

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

一:用户控件(UserControl)

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

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

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

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

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

二:资源文件

     先前文章我也说过,资源就类似于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>
  7.  

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

三:了解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. }

 

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

五:依赖属性

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

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

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

属性来显示当前时间。


还没有评论.