public object?Convert(object value, Type targetType, object parameter, CultureInfo culture) { // Allow 'value' to be non-boolean, where not-null == true if (!(value is bool b)) { b = value != null; } if (!(parameter is string s)) { return(null); } try { var c = s.Split('|'); if (c.Length != 2) { throw new Exception($"{nameof(BoolSelect)} parameter has the incorrect format. Expected '<true_value>|<false_value>'"); } var val = b ? c[0] : c[1]; // Special case conversions not handled by 'ConvertTo' if (targetType == typeof(Colour32)) { return(Colour32.Parse(val)); } if (targetType == typeof(Color)) { return(Colour32.Parse(val).ToMediaColor()); } if (targetType == typeof(Brush)) { return(Colour32.Parse(val).ToMediaBrush()); } if (targetType == typeof(Thickness)) { var i = (int?)Util.ConvertTo(val, typeof(int)) ?? 0; return(new Thickness(i)); } if (targetType == typeof(ImageSource)) { // Use: ConverterParameter='image_key1|image_key2' // Image keys should be static resource keys. // Only works if the resources are in App.xml. var res = Application.Current.TryFindResource(val); res ??= Application.Current.MainWindow.TryFindResource(val); res ??= Application.Current.Windows.Cast <Window>().Select(x => x.TryFindResource(val)).FirstOrDefault(x => x != null); return(res); } return(Util.ConvertTo(val, targetType)); } catch { // Handle this silently so that runtime editing XML works return(null); } }
// Notes: // - Parameter should be 'case0:value0|case1:value1|case2:value2|default_value' // where 'value' is a string that is convertable to 'targetType'. // - Any value with no 'case' is assumed to be the default value. // The default case should always be last public object?Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (!(value is Enum e)) { return(null); } if (!(parameter is string s)) { return(null); } try { // Look for a matching case foreach (var pair in s.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)) { var case_value = pair.Split(':'); // Default case? if (case_value.Length == 1) { return(InterpretValue(case_value[0])); } // Valid 'case:value' pair? if (case_value.Length != 2) { continue; } // Case name is not a member of the enum if (!Enum.IsDefined(value.GetType(), case_value[0])) { continue; } // Case matches 'value'? var cas = Enum.Parse(value.GetType(), case_value[0]); if (!Equals(cas, value)) { continue; } // Interpret the value to the target type return(InterpretValue(case_value[1])); } return(null); } catch { // Handle this silently so that runtime editing XML works return(null); } // Convert the string to the target type object?InterpretValue(string val) { // Special case conversions not handled by 'ConvertTo' if (targetType == typeof(Colour32)) { return(Colour32.Parse(val)); } if (targetType == typeof(Color)) { return(Colour32.Parse(val).ToMediaColor()); } if (targetType == typeof(Brush)) { return(Colour32.Parse(val).ToMediaBrush()); } if (targetType == typeof(Thickness)) { var i = (int?)Util.ConvertTo(val, typeof(int)) ?? 0; return(new Thickness(i)); } if (targetType == typeof(ImageSource)) { // Use: ConverterParameter='image_key1|image_key2' // Image keys should be static resource keys. // Only works if the resources are in App.xml. var res = Application.Current.TryFindResource(val); res ??= Application.Current.MainWindow.TryFindResource(val); res ??= Application.Current.Windows.Cast <Window>().Select(x => x.TryFindResource(val)).FirstOrDefault(x => x != null); return(res); } return(Util.ConvertTo(val, targetType)); } }