欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

[WPF]Binding的Converter和Validator

系統 2418 0

不拘一格用數據的Converter

上篇文已經說明,Binding就是數據源與目標之間的“關聯”。大多數情況下,數據從Source到Target以及從Target返回Source都是“直來直去”的,但有些場景卻需要我們對數據做些轉換才能為我所用。舉兩個典型的例子:

  • 如果數據源里的值是Y和N,如果是Y,那么UI上的CheckBox就被勾選,否則就不勾選,這就需要我們把string(也許是char)類型的數據轉換成bool?類型再使用。如果Binding是TwoWay的,CheckBox的勾選操作還會把值傳回數據源。
  • 如果“評論內容”TextBox里沒有內容,則“提交”Button不可以點擊。這是個典型的OneWay數據Binding,因為只有TextBox去影響Button的份兒。具體如何實現,大家可以先猜猜;)

想要實現這類的轉換,就需要為Binding這個“綠色通道”設置“關卡”,這里我們用到的關卡就是“數據轉換器”(Data Converter)。Converter實際上就是一個類,它這個類有個要求——它需要實現 IValueConverter 這個接口。這個接口的內容非常簡單——只有兩個方法,它們分別是:

  • Convert方法 :按照你的要求,把從數據源傳來的數據轉成你想要的數據——至于是加減乘除還是煎炒炸燉,那就要看你怎么實現函數體了
  • ConvertBack 方法:如果Binding是TwoWay的,那么數據目標會回傳經用戶改動后的數據,這時候你就不得不把數據轉換回數據源里的格式——大多數情況下,它是Convert方法的逆運算,具體情況還要具體分析。(不過,熟飯估計怎么著也變不成生米了,呵呵~~)

?下面是第一個例子的核心代碼,我來一步一步實現。

第一步 :先聲明一個類。我的習慣是 用Converter開頭,后綴是“源類型2目標類型” ,這里的“2”是“to”的意思。

?

[csharp] ? view plain copy
?
  1. class ?ConverterYN2TF??
  2. {??
  3. ??
  4. }??

第二步 :讓這個類實現 IValueConverter 接口。這里有個使用VS2008的小竅門——在類名后寫上“: IValueConverter ”后,按下鍵盤上的“Shift+Alt+F10”會彈出VS2008的智能菜單,選擇其中的第一項“實現IValueConverter的方法”,VS2008會自動為我們生成需要實現的方法體:

[csharp] ? view plain copy
?
  1. class ?ConverterYN2TF?:?IValueConverter??
  2. {??
  3. ????#region?IValueConverter?Members ??
  4. ??
  5. ???? public ? object ?Convert( object ?value,?Type?targetType,? object ?parameter,?System.Globalization.CultureInfo?culture)??
  6. ????{??
  7. ???????? throw ? new ?NotImplementedException();??
  8. ????}??
  9. ??
  10. ???? public ? object ?ConvertBack( object ?value,?Type?targetType,? object ?parameter,?System.Globalization.CultureInfo?culture)??
  11. ????{??
  12. ???????? throw ? new ?NotImplementedException();??
  13. ????}??
  14. ?
  15. ????#endregion ??
  16. }??

第三步 :添加Attribute。這步不是必需的,但加上有是有好處的——告訴Converter數據的源類型與目標類型各是什么。值得注意的是,CheckBox的IsChecked屬性是bool?類型的(可空bool類型),意思是說可以是True/False/Null三種值,表現在UI上就是勾選/不勾選/中間態。如果想讓CheckBox能顯示中間態,需要把它的IsThreeState屬性設為True。

[csharp] ? view plain copy
?
  1. [ValueConversion( typeof ( string ),? typeof ( bool ?))]? //數據的源類型是string,目標類型是bool? ??
  2. class ?ConverterYN2TF?:?IValueConverter??
  3. {??
  4. ?
  5. ????#region?IValueConverter?Members ??
  6. ??
  7. ???? public ? object ?Convert( object ?value,?Type?targetType,? object ?parameter,?System.Globalization.CultureInfo?culture)??
  8. ????{??
  9. ???????? throw ? new ?NotImplementedException();??
  10. ????}??
  11. ??
  12. ???? public ? object ?ConvertBack( object ?value,?Type?targetType,? object ?parameter,?System.Globalization.CultureInfo?culture)??
  13. ????{??
  14. ???????? throw ? new ?NotImplementedException();??
  15. ????}??
  16. ?
  17. ????#endregion ??
  18. }??

第四步:實現這兩個方法。在開始動手前,我們先分析一下這兩個方法的參數和返回值。

首先,這兩個方法的參數和返回值都是object類型的,之所以這樣做,是因為接口的設計者并不知道你要傳入和傳出的數據是什么類型的,只好用它們“絕對正確”的基類——object了。

其次,對于Convert方法來說,?value是從數據源傳來的數據,返回值是轉換好后發送給數據目標的數據。對于ConvertBack方法正好反過來,value是從數據目標(比如UI)傳回來的數據,返回值是要與數據源匹配的數據。

再次,偶爾我們會用到parameter那個參數。比如在轉換某些數據的時候,我們需要依賴一些其它的外部數據來輔助我們的數據轉換,這時候就可以在parameter上打主意了。如果想傳多個參數的話,可以把這些參數打包成數組或者class/struct等數據結構再傳進來。在我們工作的代碼中用到過一次parameter,我為我的Converter類準備了一個帶參數的構造函數,把外部的輔助數據傳給Converter

最后,如果你的Binding是OneWay的,那么恭喜你——你的ConvertBack函數體隨便怎么實現都可以——因為它不可能被調用。

完成的類是這樣的:

[csharp] ? view plain copy
?
  1. [ValueConversion( typeof ( string ),? typeof ( bool ?))]? //數據的源類型是string,目標類型是bool? ??
  2. class ?ConverterYN2TF?:?IValueConverter??
  3. {??
  4. ???? public ? object ?Convert( object ?value,?Type?targetType,? object ?parameter,?System.Globalization.CultureInfo?culture)??
  5. ????{??
  6. ???????? string ?str?=?System.Convert.ToString(value);??
  7. ???????? switch ?(str)??
  8. ????????{??
  9. ???????????? case ? "Y" :??
  10. ???????????????? return ? true ;??
  11. ???????????? case ? "N" :??
  12. ???????????????? return ? false ;??
  13. ???????????? default :??
  14. ???????????????? return ? null ;??
  15. ????????}??
  16. ????}??
  17. ??
  18. ???? public ? object ?ConvertBack( object ?value,?Type?targetType,? object ?parameter,?System.Globalization.CultureInfo?culture)??
  19. ????{??
  20. ???????? bool ??b?=?System.Convert.ToBoolean(value);??
  21. ???????? switch ?(b)??
  22. ????????{??
  23. ???????????? case ? true :??
  24. ???????????????? return ? "Y" ;??
  25. ???????????? case ? false :??
  26. ???????????????? return ? "N" ;??
  27. ???????????? default :??
  28. ???????????????? return ? "Null" ;??
  29. ????????}??
  30. ????}??
  31. }??

使用這個類的方法是將Binding實例的Converter屬性設置為這個類的一個實例:

[csharp] ? view plain copy
?
  1. checkBox1.IsThreeState?=? true ;??
  2. Binding?binding?=? new ?Binding( "Text" );??
  3. binding.Source?=?textBox1;??
  4. binding.Converter?=? new ?ConverterYN2TF();? //?設定Converter ??
  5. this .checkBox1.SetBinding(CheckBox.IsCheckedProperty,?binding);??

?

至于上面的第二個例子,留給大家自己動手去實現吧。想一想:怎樣才能讓Button的IsEnable屬性與TextBox中文本的有無關聯上呢??

? 讓數據“干干凈凈”的Validation

再讓我們來看看如何對數據進行“安檢”。?

首先,這里有一個“霸王條款”——Binding認為從數據源出去的數據都是“干凈”的,所以不進行校驗;只有從數據目標回傳的數據才有可能是“臟”的,需要校驗。

其次,對于一個Binding而言,Converter只能有一個,而校驗條件可以是好幾個——它們存儲在Binding的ValidationRules這個集合里。其實,數據校驗與轉換做的事兒差不多。

下面給出一個例子:我們以一個Slider為數據源,它的滑塊可以從Value=0滑到Value=100;同時,我們以一個TextBox為數據目標,并通過Validation限制它只能將20到35之間的數據傳回數據源。現實當中恐怕很少有這么干的,我們這個例子只是為了說明校驗的使用方法:)

若要創建一個自定義的校驗條件,需要聲明一個類,并讓這個類派生自ValidationRule類。ValidationRule只有一個名為Validate的方法需要我們實現,這個方法的返回值是一個ValidationResult類型的實例——這個實例攜帶著兩個信息:

  • bool類型的 IsValid屬性告訴Binding回傳的數據是否合法
  • object類型(一般是存儲一個string)的ErrorContent屬性告訴Binding一些信息,比如當前是進行什么操作而出現的校驗錯誤等等,一般我會把這些信息寫進Log文件里

實現好的類是這樣的:

[csharp] ? view plain copy
?
  1. public ? class ?MyValidationRule?:?ValidationRule??
  2. {??
  3. ???? public ? override ?ValidationResult?Validate( object ?value,?System.Globalization.CultureInfo?cultureInfo)??
  4. ????{??
  5. ???????? double ?d?=?0.0;??
  6. ???????? if ?( double .TryParse(( string )value,? out ?d)?&&?d?>=?20?&&?d?<=?35)??
  7. ????????{??
  8. ???????????? return ? new ?ValidationResult( true ,? "OK" );??
  9. ????????}??
  10. ???????? else ??
  11. ????????{??
  12. ???????????? return ? new ?ValidationResult( false ,? "Error" );??
  13. ????????}??
  14. ????}??
  15. }??

在代碼里這樣使用它:

[csharp] ? view plain copy
?
  1. Binding?binding?=? new ?Binding( "Value" );??
  2. binding.Source?=?slider1;??
  3. binding.UpdateSourceTrigger?=?UpdateSourceTrigger.PropertyChanged;??
  4. binding.ValidationRules.Add( new ?MyValidationRule());? //?加載校驗條件 ??
  5. textBox1.SetBinding(TextBox.TextProperty,?binding); ?

[WPF]Binding的Converter和Validator


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 99色吧| 九草在线 | 国产一区二区三区免费观看 | 日韩不卡在线 | 免费大香伊蕉在人线国产 | 日韩久久一区二区三区 | a在线观看免费 | 国产乱色精品成人免费视频 | 日韩视频一区二区三区 | 天堂av免费观看 | 国产成人无码AA片免费看 | 日韩在线免费 | 午夜看片免费 | 国内精品久久久久久99蜜桃 | 日本黄色免费网站 | 99精品国产高清一区二区麻豆 | 99精品影视| 色婷婷影院 | 加勒比久久综合 | 97风流梦电影 | 久久99精品这里精品动漫6 | 日韩中文字幕视频在线 | 三级毛片黄色 | 999精品视频| 亚洲精品人人 | 九九视频在线观看 | 九九亚洲 | 欧美精品一二三区 | 日韩欧美一区二区三区 | 999宝藏网 | 国产区视频在线观看 | 抱着cao才爽免费观看 | 精品视频在线免费观看 | 日韩精品亚洲人成在线播放 | 国产亚洲一区二区三区 | 国产精品视频在线播放 | 亚洲欧美小视频 | 伊人久久99亚洲精品久久频 | 99久久精品国产一区二区三区 | 好爽好大www视频在线播放 | 天天干夜夜操 |