General-purpose Converters for WPF Converters
The converter in WPF is a very good data type conversion solution, which is practical and powerful. It is used to convert the source data to the type required by WPF itself and is not aggressive to the data entity, it is frequently used in the project. Therefore, mastering converters is a required skill in WPF development.
When I first came into contact with the converter, I did not consider versatility. Every time I encountered a conversion requirement, I would create a new converter. Over time, the converter in the project has become more versatile.
Of course, this is intolerable. I decided to use a general-purpose converter to replace the vast majority of conversion operations with the same nature, and adapt to different conversion scenarios by agreeing on a set of parameter rules, achieve the purpose of converter reuse.
There are two types of converters: IValueConverter (single-value converter) and IMultiValueConverter (multi-value converter)
Single-value universal converter ObjectConverter
Parameter rules [compare value 1 | compare value 2: true return value: false return value]
Take a closer look, this parameter rule actually has the same meaning as a ternary expression. If the source data is equal to the value of 1 or 2, true is returned. Otherwise, false is returned.
With this rule, you can implement General conversion requirements. The ObjectConverter source code is as follows:
Public class ObjectConverter: IValueConverter {public object Convert (object value, Type targetType, object parameter, CultureInfo culture) {string [] parray = parameter. toString (). toLower (). split (':'); // segment the parameter character. parray [0] is a comparison value, and parray [1] is a true return value, parray [2] returns false if (value = null) return parray [2]; // if the data source is empty, false is returned by default if (parray [0]. contains ("|") // returns parray [0] When multiple comparison Values exist. split ('| '). conta Ins (value. ToString (). ToLower ())? Parray [1]: parray [2]; // return parray [0]. Equals (value. ToString (). ToLower ())? Parray [1]: parray [2]; // single-value Comparison} public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture) {var returnValue = "otherValue "; string [] parray = parameter. toString (). toLower (). split (':'); if (value = null) return returnValue; var valueStr = value. toString (). toLower (); if (valueStr! = Parray [1]) return returnValue; else return parray [0]. Contains ('| ')? Parray [0]. Split ('|') [0]: parray [0];}
Use of ObjectConverter
1 <converter: ObjectConverter x: Key = "objConverter"/> 2 3 <Border Visibility = "{Binding PanelStatus, Converter = {StaticResource objConverter}, ConverterParameter = true: Visible: collapsed} "> 4 5 <Border Background =" {Binding BgColor, Converter = {StaticResource objConverter}, ConverterParameter = 1: Red: blue} "> 6 7 <TextBlock Text =" {Binding Type, Converter = {StaticResource objConverter}, ConverterParameter = 1 | 2: VIP member: Regular member} "/>
MultiObjectConverter
Parameter rules [comparison values of each group: Comparison condition (& amp; or |): true return value: false return value: Return Value Type enumeration]
The parameter rules of the multi-value converter are slightly troublesome, but they are similar to the ternary expressions, except that the comparison conditions and return value enumeration types are added, someone asks why the single-value converter does not need to declare the return value enumeration and the multi-value converter needs it. This is because if the return value of the multi-value converter does not return the actual type, the return type will be invalid, the default WPF converter does not seem to be useful. This problem is also being studied, so first define a type of return value enumeration to convert the return value. Consider a temporary solution.
1 public class MultiObjectConverter: IMultiValueConverter 2 {3 /// <summary> 4 // multi-value converter 5 /// </summary> 6 /// <param name = "values"> parameter value array </param> 7 /// <param name = "parameter"> 8 /// <para> parameter </para> 9 /// <para> comparison value of each group: comparison condition (& amp; or |): true return value: false return value type enumeration </para> 10 // <para> v1; v2-1 | v2-2; v3: & amp;: Visible: Collapsed: 1 </para> 11 /// </param> 12 /// <returns> </returns> 13 public object Convert (object [] Values, Type targetType, object parameter, System. globalization. cultureInfo culture) 14 {15 string [] param = parameter. toString (). toLower (). split (':'); // segment the parameter string into 16 string [] compareValues = param [0]. split (';'); // splits the comparison value segment into array 17 if (values. length! = CompareValues. length) // compare the number of source data and comparison parameters. 18 return ConvertValue (param [3], param [4]); 19 var trueCount = 0; // number of results meeting the condition 20 var currentValue = string. empty; 21 IList <string> currentParamArray = null; 22 for (var I = 0; I <values. length; I ++) 23 {24 currentValue = values [I]! = Null? Values [I]. toString (). toLower (): string. empty; 25 if (compareValues [I]. contains ("|") 26 {27 // The current comparison value segment Contains multiple comparison values 28 currentParamArray = compareValues [I]. split ('|'); 29 trueCount + = currentParamArray. contains (currentValue )? 1: 0; // The condition is met. The result is + 130} 31 else32 {33 trueCount + = compareValues [I]. Equals (currentValue )? 1: 0; // The condition is met. The result is + 134} 35} 36 currentParamArray = null; 37 currentValue = string. empty; 38 var compareResult = param [1]. equals ("&")? 39 trueCount = values. Length: 40 trueCount> 0; // compare 41 return ConvertValue (compareResult? Param [2]: param [3], param [4]); 42} 43 44 public object [] ConvertBack (object value, Type [] targetTypes, object parameter, System. globalization. cultureInfo culture) 45 {46 throw new NotImplementedException (); 47} 48 49 private object ConvertValue (string result, string enumStr) 50 {51 var convertResult = (ConvertResult) int. parse (enumStr); 52 if (convertResult = ConvertResult. display type) 53 return result. equals ("Collapsed ")? Visibility. collapsed: Visibility. visible; 54 if (convertResult = ConvertResult. boolean) 55 return System. convert. toBoolean (result); 56 return null; // follow-up extension 57} 58 59 private enum ConvertResult60 {61 display type = boolean type = string type = 64 integer = decimal type = 66 brush type = style type = 869 template type =} 70}
Use of MulitObjectConverter
1 <TextBlock Text="test">2 <TextBlock.Visibility>3 <MultiBinding Converter="{StaticResource mobjConverter}"4 ConverterParameter="1|2;true:|:Visible:Collapsed:1">5 <Binding Path="Filed1"/>6 <Binding Path="Filed2"/>7 </MultiBinding>8 </TextBlock.Visibility>9 </TextBlock>
The single-value universal converter and multi-value universal converter have been completed. You can customize ConverterParameter rules as needed to achieve flexible expansion. Welcome to group discussion 372754241