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>

 

最后感謝一直關注此系列的朋友,希望你們有一絲收獲。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM