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>

 

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

posted @ 2012-07-15 17:41  一线码农  阅读(14967)  评论(22编辑  收藏  举报