WPF學習之Binding的學習(一)

来源:http://www.cnblogs.com/Melvin-Dong/archive/2016/08/06/5743142.html
-Advertisement-
Play Games

程式的本質是數據加演算法。通俗一點來說呢,其實就是用戶給一個輸入,經過演算法的處理之後,電腦反饋一個輸出給用戶。可以很清楚的看出,在這個過程中,處於主導地位的是數據。但是,當我們在進行圖形用戶界面(Graphic User Interface,GUI)編程的時,數據總是處於被動地位。也就是說,程式總是 ...


  程式的本質是數據加演算法。通俗一點來說呢,其實就是用戶給一個輸入,經過演算法的處理之後,電腦反饋一個輸出給用戶。可以很清楚的看出,在這個過程中,處於主導地位的是數據。但是,當我們在進行圖形用戶界面(Graphic User Interface,GUI)編程的時,數據總是處於被動地位。也就是說,程式總是在等待接收來自UI的消息/事件,在這些事件被處理之後,才會反饋給用戶一個輸出。我們用Data Binding可以在GUI編程時讓數據回到程式的核心。

  1、Data Binding在WPF中的地位

  我們之前也提到過,程式的本質就是數據+演算法。數據一般會在存儲、邏輯和展示三個層進行流通,相對應的來講,演算法一般會分佈在以下幾處:

  A、資料庫內部

  B、讀取和寫入數據

  C、業務邏輯

  D、數據展示

  E、界面與邏輯的交互

  我們很容易能夠理解,A、B兩部分的演算法一般很穩定,我們在編程的過程中很少去改動他們,同時他們的復用性也是很高。C這一部分包含大量的演算法,因為其與客戶的需求關係最為緊密,這也就導致這一部分的代碼最複雜、變動最大。D、E兩部分主要負責UI與邏輯的交互,也會有相應的演算法。 顯而易見,包含大部分代碼的C部分最為重要,是開發的重中之重,但是在我們開發的過程中,D、E兩個部分卻經常成為麻煩的來源。問題的根源就在於邏輯層與展示層的地位不固定——當我們去編程實現用戶的需求是,很顯然邏輯層處於中心地位,但是在UI交互的過程中,展示層又處於中心地位。WPF作為一種專門的展示層技術,在其華麗的外觀這種表層現象之下,更重要的是他在很層次上幫助程式員把思維的重心固定在邏輯層,無論在什麼情況下,展示層總是處於從屬地位。是什麼讓WPF擁有這種“超能力”呢?關鍵就在於WPF引進了Data Binding以及與之配套的Dependency Property和Data Template。

  我們常常說在WPF開發中,是“數據驅動UI”,那麼究竟什麼事“數據驅動UI”呢?其實,在WPF編程中,Data Binding起到的作用就如同現實生活中的高速公路,有了他,加工好的數據就會自動傳入到用戶界面加以顯示,被用戶修改過的數據也會通過他自動回傳到邏輯層……周而複始,程式的邏輯層就想一個引擎一樣不停的運轉。

  在引入了Data Binding機制後,邏輯層和展示層之間就會是直來直去的,不涉及任何的邏輯問題。這樣帶來的好處就是用戶界面不包含演算法;而Data Binding本身就是雙向通信,所以相當於將D、E兩個部分合二為一。

  2、Binding基礎  

  什麼是Binding?我們可以將Binding看做一個橋梁,他的兩端分別是Source和Target。數據從哪裡來,那麼哪裡就是source,到哪去那就是target。一般而言,Binding的源是邏輯層的對象,Binding的對象是UI層的控制項對象。實現Binding後,數據就會源源不斷的從邏輯層通過Binding送到UI層,UI層將這些數據進行展示,這就完成了數據驅動UI的過程。同時,在這個過程中,我們可以設置源於目標之間是雙向通信還是單向通信,還可以在數據傳送的過程中對數據的準確性進行校驗甚至轉換數據的類型。

  下麵,我們來看一個最簡單的Binding的例子。

  首先,我們創建一個Student的對象,讓它作為數據源進行使用。

1 class Student
2     {        
3         private string _name;
4         public string Name
5         {
6             get{return _name;}
7             set{_name = value;}
8         }        
9     }

  這個類很是簡單,簡單到只有一個string類型的Name屬性。前面說過數據源是一個對象,一個對象本身可能會有很多數據,這些數據又通過屬性暴露給外界。那麼其中哪個元素是你想通過Binding送達UI元素的呢,換句話說,UI元素關心的是哪個屬性值的變化呢?這個屬性值稱之為Binding的路徑(Path)。但光有屬性還不行-------Binding是一種自動機制,當值變化後屬性要有能力通知Binding,讓Binding把變化傳遞給UI元素。怎樣才能讓一個屬性具備這種通知Binding值已經改變的能力呢?方法是在屬性的Set語句中激發一個PropertyChanged事件。這個事件不需要我們自己聲明,我們要做的事是讓作為數據源的類實現System.ComponentModel名稱空間中的INotifyPropertyChanged介面。當為Binding設置了數據源之後,Binding就會自動偵聽來自這個介面PropertyChanged事件。

  實現INotifyPropertyChanged介面的類看起來是這樣:

 1 class Student:INotifyPropertyChanged
 2     {
 3         public event PropertyChangedEventHandler PropertyChanged;
 4         private string _name;
 5 
 6         public string Name
 7         {
 8             get
 9             {
10                 return _name;
11             }
12 
13             set
14             {
15                 _name = value;
16                 //激發事件
17                 if (PropertyChanged != null)
18                 {
19                     this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
20                 }
21             }
22         }        
23     }

  當我們這樣升級之後,只要Student中Name屬性的值一變化,PropertyChanged事件就會被激發,Binding接收到這個事件後發現事件的消息告訴它是Name屬性值發生了變化,於是通知Binding目標端的UI元素顯示新的值。

  現在,我們在窗體上準備一個Text和一個Button,代碼如下:

 1 <Window x:Class="_1_Binding基礎.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:_1_Binding基礎"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="110" Width="300">
 9     <Grid>
10         <StackPanel>
11             <TextBox Name="txtBoxName" Margin="5" BorderBrush="Black"></TextBox>
12             <Button Content="Add Age" Click="Button_Click" Margin="5"></Button>
13         </StackPanel>
14     </Grid>
15 </Window>

  接下來,我們使用Binding將數據源和UI元素連接起來,具體代碼如下:

 1 public partial class MainWindow : Window
 2     {
 3         Student stu;
 4         public MainWindow()
 5         {
 6             InitializeComponent();
 7             //準備數據源
 8             stu = new Student();
 9 
10             //準備Binding
11             Binding binding = new Binding();
12             binding.Source = stu;
13             binding.Path = new PropertyPath("Name");
14 
15             //使用Binding連接數據源與Binding目標
16             BindingOperations.SetBinding(this.txtBoxName, TextBox.TextProperty, binding);
17 
18 
19         }
20 
21         private void Button_Click(object sender, RoutedEventArgs e)
22         {
23             stu.Name += "Button";
24         }
25     }

  下麵我們逐一的解讀一下這一段代碼。在準備Binding的部分,首先用“Binding binding = new Binding();”聲明Binding類型變數並創建實例,之後用“binding.Source = stu;”為Binding指定源,用“binding.Path = new PropertyPath("Name");”語句為Binding指定訪問路徑。

  把數據源和目標連接在一起的任務是使用“BindingOperations.SetBinding(...)”方法完成的,這個方法的3個參數是我們記憶的重點:

  第一個參數是指定Binding的目標,本例中的this.textBoxName。

  與數據源的Path原理類似,第二個參數用於為Binding指明為Binding指明把這個數據送達目標的哪個數據。

  第三個參數很明顯,就是指定使用哪個Binding實例將數據源和目標關聯起來。

  最後我們在Button的Click事件中對Name屬性進行了更新,運行程式,點擊Button,可以看到如下的結果:

 

  先用這個例子作為基礎,後面我們來研究Binding的每個特點。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • linux系統:Centos6.5 1.首先確定是不是圖形化界面: yum -y groupinstall Desktop "X Window System" chinese-support 2.先備份數據: cd /etc/yum.repos.d/(進入對應文件夾)→mv CentOS-Base. ...
  • 1.安裝redis 2.編寫redis優化腳本 3.打包 ...
  • mac遠程windows系統比較容易,但是windows遠程mac就相對複雜一點,需要藉助第三方工具來實現。 下麵給出簡要的遠程步驟: 1、登錄mac,點擊蘋果圖標,然後單擊【系統偏好設置...]。如下圖所示: 2、在【系統偏好設置】界面中,單擊【共用】,如下圖所示: 3.在【共用】中勾選【屏幕共用 ...
  • 這篇文章主要介紹了js獲取及判斷鍵盤按鍵的方法,涉及JavaScript鍵盤事件的獲取及鍵值的判定技巧,具有一定參考借鑒價值,需要的朋友可以參考下 這篇文章主要介紹了js獲取及判斷鍵盤按鍵的方法,涉及JavaScript鍵盤事件的獲取及鍵值的判定技巧,具有一定參考借鑒價值,需要的朋友可以參考下 本文 ...
  • FPM功能簡單說就是將一種類型的包轉換成另一種類型。FPM的github:https://github.com/jordansissel/fpm 1.支持的源類型包: dir: 將目錄打包成所需要的類型,可以用於源碼編譯安裝的軟體包 rpm: 對rpm進行轉換 gem: 對rubygem包進行轉換 ...
  • 鏈接:http://pan.baidu.com/s/1eS4rR9o 密碼:0uws 手機電腦全套破解的教程正在重新打包,很快就可以了! ...
  • 前言: 此方法只能借鑒,如果網友安裝失敗,後果自負。 借鑒的書籍《跟老男孩學Linux運維 Web集群實戰》 文章所使用的Mysql:https://yunpan.cn/Oc6RkgKRFVUvex 訪問密碼 0000 其他軟體下載:http://mirror.bit.edu.cn/mysql/Do ...
  • 回到目錄 我們知道在Linq里的分組groupby可以對集合中一個或者多個欄位進行分組,並對其中一個屬性進行聚合,而Linq為我們提供了多種聚合方法,由aver,sum,count等,而在大叔許可權體系中,以上幾種聚合是不夠的,因為我們需要對許可權欄位進行按位聚合,或者說對它進行按位的或運算,這對於學過 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...