一個通用的WPF值轉換器


在WPF中應用數據綁定時經常需要做一些簡單的邏輯判斷。

比如ViewModel中有一個HasError(布爾值)的屬性表示是否有錯誤。我需要將它綁定於Button的IsEnable屬性上,即:當沒有錯誤時Button可用。這時就需要將HasError取反。WPF默認的綁定引擎是不支持的。

 

還有一種情況比如ViewModel中有一個Sex(int值)的屬性表示性別,我需要將它綁定到TextBlock上,當值為1時顯示男,值為2時顯示女。WPF默認綁定也是不支持這種判斷的。

 

於是一個通用的值轉換器就誕生了,用法如下:

<Button IsEnabled="{Binding HasError, Converter={StaticResource GenericTypeConverter}, ConverterParameter='IsReverse=True'}">OK</Button>

IsReverse參數表示是否取返,如果轉換的值為true則變為false,反之亦然。

 

<TextBlock Text="{Binding Sex, Converter={StaticResource GenericTypeConverter}, ConverterParameter='Alias=1:男|2:女|other:未知'}" />

Alias參數表示將值映射為字符串,other表示當遇到沒有指定的值時顯示的文本

 

另外bool to Visibility的轉換可以自動進行,不需要指定參數。

 

有意見歡迎指正

 

完整代碼如下:

 

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;

namespace MoodSunshiny.WPF.Converter
{
     ///   <summary>
    
///  一個通用的類型轉換器,可以提供更多轉換控制參數
    
///   </summary>
     public  class GenericTypeConverter : IValueConverter
    {
         ///   <summary>
        
///  是否反轉轉換源參數值
        
///  僅對bool類型的值有效
        
///   </summary>
         private  bool IsReverse {  getset; }

         ///   <summary>
        
///  用於將轉換結果映射為其它字符串
        
///  例如:Alias=True:是|False:否
        
///   </summary>
         private Dictionary< objectstring> Alias {  getset; }
        
         ///   <summary>
        
///  解析轉換參數
        
///   </summary>
         private  void AnalyseConvertParameter( string convertParameter)
        {
             /* 設置參數默認值 */
            IsReverse =  false;
            Alias =  null;

             if (! string.IsNullOrEmpty(convertParameter))
            {
                 var pkvs = convertParameter.Split( new  char[] {  ' , ' }, StringSplitOptions.RemoveEmptyEntries);
                 foreach ( var pkv  in pkvs)
                {
                     var pkvo = pkv.Split( new  char[] {  ' = ' }, StringSplitOptions.RemoveEmptyEntries);
                     if (pkvo.Length !=  2)
                         throw  new NotSupportedException( " 不支持設置: " + pkv);
                     var pk = pkvo[ 0].Trim();
                     var pv = pkvo[ 1].Trim();

                     switch (pk)
                    {
                         case  " IsReverse ":
                             bool b;
                             if (! bool.TryParse(pv,  out b))
                                 throw  new NotSupportedException( " 參數取值錯誤: " + pkv);
                             else
                                IsReverse = b;
                             break;
                         case  " Alias ":
                            {
                                Alias =  new Dictionary< objectstring>();
                                 var dfkvs = pv.Split( new  char[] {  ' | ' }, StringSplitOptions.RemoveEmptyEntries);
                                 foreach ( var dfkv  in dfkvs)
                                {
                                     var dfkvo = dfkv.Split( new  char[] {  ' : ' }, StringSplitOptions.RemoveEmptyEntries);
                                     if (dfkvo.Length !=  2)
                                         throw  new NotSupportedException( " 不支持設置: " + dfkvo);
                                     var dfk = dfkvo[ 0].Trim();
                                     var dfv = dfkvo[ 1].Trim();

                                     object oKey =  null;
                                     int i;
                                     if (dfk.Equals( " true ", StringComparison.OrdinalIgnoreCase))
                                        oKey =  true;
                                     else  if (dfk.Equals( " false ", StringComparison.OrdinalIgnoreCase))
                                        oKey =  false;
                                     else  if (dfk.Equals( " other ", StringComparison.OrdinalIgnoreCase))
                                        oKey =  " other ";
                                     else  if ( int.TryParse(dfk,  out i))
                                        oKey = i;
                                     else
                                         throw  new NotSupportedException( " 參數取值錯誤: " + dfkv);

                                    Alias[oKey] = dfv;
                                }
                            }
                             break;
                         default:
                             throw  new NotSupportedException( " 不支持的參數名: " + pk);
                    }
                }
            }
        }

         public  object Convert( object value, Type targetType,  object parameter, System.Globalization.CultureInfo culture)
        {
            AnalyseConvertParameter(parameter  as  string);

             try
            {
                 var sourceType = value.GetType();
                 if (IsReverse && sourceType ==  typeof( bool))
                    value = !(( bool)value);

                 if (targetType ==  typeof( string))
                {
                     if (Alias !=  null && Alias.ContainsKey(value))
                         return Alias[value];
                     else  if (Alias !=  null && Alias.ContainsKey( " other "))
                         return Alias[ " other "];
                     else
                         return  value ==  null ?  "" : value.ToString();
                }
                 if (targetType ==  typeof( bool))
                {
                     if (sourceType ==  typeof(Visibility))
                         return (Visibility)value == Visibility.Visible;
                }
                 else  if (targetType.IsEnum)
                {
                     if (sourceType ==  typeof( bool) && targetType ==  typeof(Visibility))
                    {
                         return ( bool)value ? Visibility.Visible : Visibility.Collapsed;
                    }
                     else
                    {
                         return Enum.Parse(targetType, value.ToString(),  true);
                    }
                }
                 else
                {
                     return System.Convert.ChangeType(value, targetType);
                }

                 return System.Convert.ChangeType(value, targetType);
            }
             catch
            {
                 return  null;
            }
        }

         public  object ConvertBack( object value, Type targetType,  object parameter, System.Globalization.CultureInfo culture)
        {
             return Convert(value, targetType, parameter, culture);
        }
    }
}

 


免責聲明!

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



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