WPF入門:數據綁定

来源:http://www.cnblogs.com/liunlls/archive/2016/12/06/wpf-binding.html
-Advertisement-
Play Games

上一篇我們將 "XAML" 大概做了個瞭解 ,這篇將繼續學習WPF數據綁定的相關內容 數據源與控制項的Binding 作為數據傳送UI的通道,通過 介面的 事件通知 數據屬性發生改變 通過Binding關聯UI控制項元素 控制項之間的Binding 我們也可以通過後臺C 代碼實現 統計文本字元長度 Bin ...


上一篇我們將XAML大概做了個瞭解 ,這篇將繼續學習WPF數據綁定的相關內容

數據源與控制項的Binding

Binding作為數據傳送UI的通道,通過INotityPropertyChanged介面的PropertyChanged事件通知Binding數據屬性發生改變

  public class Product : INotifyPropertyChanged
  {
      private string name;
      public string Name
      {
          get { return name; }
          set
          {
              name = value;
              if (PropertyChanged != null)
              {
                  this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
              }
          }
      }
      public event PropertyChangedEventHandler PropertyChanged;
  }

通過Binding關聯UI控制項元素

   this.txtOfProduct.SetBinding(TextBox.TextProperty, new Binding() { Path = new PropertyPath("Name"), Source = p });

控制項之間的Binding

 <TextBox x:Name="TextBox1" Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}"></TextBox>
 <Slider x:Name="slider1" Margin="5"></Slider>


我們也可以通過後臺C#代碼實現

 TextBox1.SetBinding(TextBox.TextProperty, new Binding("Value") { ElementName = "slider1", Mode=BindingMode.OneWay });

統計文本字元長度

 <TextBox x:Name="TextBox1"  Margin="5"  TextWrapping="Wrap" ></TextBox>
 <TextBlock Margin="5"  TextAlignment="Right" Text="{Binding ElementName=TextBox1, Path=Text.Length}"></TextBlock>

Binding的Path

Path的索引器方式

  <TextBox x:Name="TextBox1"  Margin="5"  TextWrapping="Wrap" ></TextBox>
  <!--獲取Text的第三個字元-->
  <TextBlock Margin="5"  TextAlignment="Right" Text="{Binding ElementName=TextBox1, Path=Text.[2]}"></TextBlock>
  <TextBlock Margin="5"  TextAlignment="Right" Text="{Binding ElementName=TextBox1, Path=Text[2]}"></TextBlock>

當使用一個集合或者DataView作為Binding源時,如果我們想把它的預設元素作為Path來使用

 List<string> names = new List<string>() { "張三", "李四", "王五" };
 //張三
 this.TextBox1.SetBinding(TextBox.TextProperty, new Binding("/") { Source = names });
 //“張三”字元串的長度
 this.TextBox2.SetBinding(TextBox.TextProperty, new Binding("/Length") { Source = names,Mode=BindingMode.OneWay});
 //獲取“張三”字元串中的第1個字元
 this.TextBox3.SetBinding(TextBox.TextProperty, new Binding("/[0]") { Source = names, Mode = BindingMode.OneWay });

如果集合中嵌套集合,我們依然可以通過多級"/"語法把子集作為Path的元素

  class City
  {
      public string Name { get; set; }
  }

  class Province
  {
      public List<City> Citys { get; set; }
      public string Name { get; set; }
  }

  class Country
  {
      public List<Province> Provinces { get; set; }
      public string Name { get; set; }
  }
  TextBox1.SetBinding(TextBox.TextProperty, new Binding("/Name") { Source = countries });
  TextBox2.SetBinding(TextBox.TextProperty, new Binding("/Provinces/Name") { Source = countries });
  TextBox3.SetBinding(TextBox.TextProperty, new Binding("/Provinces/Citys/Name") { Source = countries });

省略Path

sys需要引用xmlns:sys="clr-namespace:System;assembly=mscorlib"

 <StackPanel.Resources>
     <sys:String x:Key="text">
         WPF入門手冊
     </sys:String>
 </StackPanel.Resources>
 <TextBox x:Name="TextBox1"  Margin="5" Text="{Binding .,Source={StaticResource ResourceKey=text}}" ></TextBox>
TextBox2.SetBinding(TextBox.TextProperty, new Binding(".") { Source = "WPF技術入門" });

沒有Path和Source,Binding可以通過DataContext獲取數據

 <StackPanel.DataContext>
     <sys:String>
         WPF入門手冊
     </sys:String>
 </StackPanel.DataContext>
 <TextBox x:Name="TextBox1"  Margin="5" Text="{Binding Mode=OneWay}" ></TextBox>

選中ListBox元素顯示對應的屬性的一個例子

 <TextBox x:Name="TextBox1"  Margin="5" ></TextBox>
 <ListBox x:Name="ListBox1"></ListBox>
  List<City> cities = new List<City>() {
      new City() { Id=1,Name="北京" },
      new City() { Id=2,Name="昆明" },
      new City() { Id=3,Name="上海" },
      new City() { Id=4,Name="廈門" },
      new City() { Id=5,Name="廣州" }
  };

  this.ListBox1.ItemsSource = cities;
  this.ListBox1.DisplayMemberPath = "Name";
  this.TextBox1.SetBinding(TextBox.TextProperty, new Binding("SelectedItem.Id") { Source = this.ListBox1 });

使用Binding的RelativeSource

Binding有明確的數據源的時,我們可以通過SoureElementName賦值辦法關聯Binding,但有事我們不知道Soure對象的名字是什麼,卻知道它與作為Binding目標對象的UI元素佈局上的相對關係,通過RelativeSourceMode枚舉設置關聯的對象關係

<Grid x:Name="g1">
    <StackPanel x:Name="s1">
        <DockPanel x:Name="d1">
            <TextBox x:Name="TextBox1"  Margin="5" ></TextBox>
        </DockPanel>
    </StackPanel>
</Grid>

後臺代碼處理

 RelativeSource rs = new RelativeSource(RelativeSourceMode.FindAncestor)
 {
     AncestorLevel = 1,
     AncestorType = typeof(StackPanel)
 };
 //將StackPanel的Name s1賦給了TextBox1的Text
 TextBox1.SetBinding(TextBox.TextProperty, new Binding("Name") { RelativeSource = rs });

也可以通過XAML的方式賦值

    <Grid x:Name="g1">
        <StackPanel x:Name="s1">
            <DockPanel x:Name="d1">
                <TextBox x:Name="TextBox1"  Margin="5" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DockPanel},AncestorLevel=1,Mode=FindAncestor}, Path=Name}" ></TextBox>
            </DockPanel>
        </StackPanel>
    </Grid>

Binding數據驗證

BindingValidationRules屬性的類型為Collection<ValidationRule>。通過實現Validate方法返回給ValidationResult對象,並設置IsVaild屬性,ErrorContent屬性可以接受一個字元串。

 public class RangValidationRule : ValidationRule
 {
     //驗證數據
     public override ValidationResult Validate(object value, CultureInfo cultureInfo)
     {
         double d = 0;
         if (double.TryParse(value.ToString(), out d))
         {
             if (d >= 1 && d <= 100)
             {
                 return new ValidationResult(true, null);
             }
         }
         return new ValidationResult(false, "數據錯誤");
     }
 }
 <TextBox x:Name="TextBox1" Margin="5"></TextBox>
 <Slider x:Name="slider1" Minimum="1" Maximum="100" Margin="5"></Slider>
 Binding binding = new Binding("Value") {
     Source=slider1,
     UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged,
 };
 binding.ValidationRules.Add(new RangValidationRule());
 this.TextBox1.SetBinding(TextBox.TextProperty, binding);

顯示錯誤提示

  public MainWindow()
  {
      InitializeComponent();

      Binding binding = new Binding("Value")
      {
          Source = slider1,
          UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
          NotifyOnValidationError = true//開啟錯誤通知
      };
      binding.ValidationRules.Add(new RangValidationRule());

      this.TextBox1.SetBinding(TextBox.TextProperty, binding);
       //註冊驗證錯誤事件
      this.TextBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(ValidationErrorNotify));
  }

  private void ValidationErrorNotify(object sender, RoutedEventArgs e)
  {
      var errors = Validation.GetErrors(this.TextBox1);
      if (errors.Count > 0)
      {
          TextBlock1.Text = errors[0].ErrorContent.ToString();
      }
  }

多路Binding

一般我們在做註冊用戶功能的時候,輸入密碼的時候都需要再確認輸入密碼,比較兩次輸入是否一致,現在我們可以通過多路Binding來簡單的實現這個功能
首先實現一個IMultiValueConverter介面功能,如果兩次密碼一致,提交按鈕狀態為可用

    public class SubmitMultiBindingConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return (!values.Cast<string>().Any(a => string.IsNullOrEmpty(a))/*驗證所有元素非空*/ &&
                values[0].ToString() == values[1].ToString())/*值1=值2*/;
            
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

XAML代碼

 <TextBox x:Name="Password" Margin="5"></TextBox>
 <TextBox x:Name="Passworder" Margin="5"></TextBox>
 <Button x:Name="Submit" Content="提交" Margin="10" Height="30" Width="100"></Button>

後臺Binding

 Binding pwdBinding = new Binding("Text") { Source = Password };
 Binding pwderBinding = new Binding("Text") { Source = Passworder };
 MultiBinding multi = new MultiBinding() { Mode=BindingMode.OneWay};
 multi.Bindings.Add(pwdBinding);
 multi.Bindings.Add(pwderBinding);
 multi.Converter = new SubmitMultiBindingConverter();
 Submit.SetBinding(Button.IsEnabledProperty, multi);


以上就是Binding常用到的功能,下篇我將繼續學習依賴屬性和WPF路由事件的相關內容



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

-Advertisement-
Play Games
更多相關文章
  • Kconfig是我們進行內核配置的關鍵文件,用於生成menuconfig的界面並生成最終確定編譯選項的 文件。關於Kconfig文件的編寫規則,在 有詳盡的敘述。這裡主要用實例進行語法分析。 config 確定了條目前面是否有選項,menuconfig界面中的條目中一共有3種主動選項,分別是 ,`` ...
  • 今天想安裝一個博客客戶端,結果安裝一直報錯“OnCatalogResult:0x80190194”,百度查到瞭解決發放再此記錄下來,以備後用。 到官網下載了一個線上安裝程式,可是一運行就提示無法安裝,顯式錯誤“OnCatalogResult:0x80190194”,如下圖所示 找到windows l ...
  • 不看廢話,直接跳到操作說明 前幾日心血來潮想把家中的舊筆記本換成Linux操作系統,算是在業餘生活中正式投入Linux的懷抱。說乾就乾,發行版選擇了Ubuntu,下載了Ubuntu16.04的ISO,下載軟碟通,製作成U盤啟動。恩,重啟電腦,U盤引導,進入安裝界面。 恩,安裝界面挺炫酷啊,還檢測到硬 ...
  • yum install pcre* yum install openssl* yum install zlib yum install zlib-devel yum install wget 查看是否已經安裝好 rpm -qa | grep "查看的內容" 2.開始安裝nginx wget http ...
  • ...
  • 關於英文對程式員的重要性,就不多說了!英語的學習,有很多,今天也不聊多,只聊英語單詞!關於單詞的記憶,找過很多方法,下載過很多軟體,後來...... ...
  • DateTime.Now.AddDays(10).ToShortDateString().ToString() addDays(整數) 一天前DateTime.Now.AddDays(-1).ToShortDateString().ToString() 一天後DateTime.Now.AddDays ...
  • 簡介 此樣式基於bootstrap-3.3.0,樣式文件里的源碼行數都是指的這個版本.CSS源文件放到了Content文件夾下的bootstrap.css WPF樣式和CSS還是不太相同,所以有些內容實現上稍有出入,有些內容用法不太一樣,有些內容並沒有實現 但至少,一些概念,尺寸和取色,還是很好的借 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...