static StackPanel GeneratePopupContent(UIElement sourceItemContainer, out UIElement iconStop, out UIElement iconArrow) { StackPanel stackPanelInPopUp = new StackPanel(); iconStop = new Path() { Data = (Geometry)TypeFromStringConverters.ConvertFromInvariantString(typeof(Geometry), @"M13.4005,19.7645 L13.3231,19.8886 C11.5316,22.8369 10.5,26.298 10.5,30 C10.5,40.7696 19.2305,49.5 30,49.5 C33.702,49.5 37.1631,48.4684 40.1115,46.6769 L40.2355,46.5995 z M30,10.5 C26.298,10.5 22.8369,11.5316 19.8886,13.3231 L19.7645,13.4005 L46.5995,40.2355 L46.6769,40.1115 C48.4684,37.1631 49.5,33.702 49.5,30 C49.5,19.2305 40.7696,10.5 30,10.5 z M30,0.5 C46.2924,0.5 59.5,13.7076 59.5,30 C59.5,46.2924 46.2924,59.5 30,59.5 C13.7076,59.5 0.5,46.2924 0.5,30 C0.5,13.7076 13.7076,0.5 30,0.5 z"), Fill = new SolidColorBrush(Colors.Red), Height = 10, Width = 10, Stretch = Stretch.Fill, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Bottom }; iconArrow = new Path() { Data = (Geometry)TypeFromStringConverters.ConvertFromInvariantString(typeof(Geometry), @"M120,60 L120,80 L160,80 L160,90 L180,70 L160,50 L160,60 z"), Fill = new SolidColorBrush(Colors.Blue), Height = 7.057, Width = 10.5, Stretch = Stretch.Fill, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Bottom }; iconArrow.Visibility = Visibility.Collapsed; stackPanelInPopUp.Orientation = Orientation.Horizontal; stackPanelInPopUp.Children.Add(sourceItemContainer); stackPanelInPopUp.Children.Add(iconStop); stackPanelInPopUp.Children.Add(iconArrow); return(stackPanelInPopUp); }
private void PrepareIndexForIndexer(PropertyInfo indexer) { Type indexType = indexer.GetIndexParameters().First().ParameterType; try { this._parsedIndex = Convert.ChangeType(this._index, indexType); } catch (Exception) { if (TypeFromStringConverters.CanTypeBeConverted(indexType)) { this._parsedIndex = TypeFromStringConverters.ConvertFromInvariantString(indexType, this._index); //todo: maybe in try / catch ? } else { this._parsedIndex = this._index; //todo: maybe null ? } } }
private static object ConvertValueIfNecessary(object value, Type targetType) { // Convert from String to the destination type: if (value is string && targetType != typeof(string)) //eg. binding "ScrollBar.Value" to "TextBox.Text" { try //this try/catch block is solely for the purpose of not raising an exception so that the GetValue finishes its thing (including handling the case where the conversion cannot be done). { value = TypeFromStringConverters.ConvertFromInvariantString(targetType, (string)value); } catch (Exception ex) { HandleException(ex); } } // Some hard-coded conversions: //todo: generalize this system by implementing "TypeConverter" and "TypeConverterAttribute" if (targetType == typeof(Color) && value is SolidColorBrush scb) //eg. binding "Border.Background" to "DropShadowEffect.Color" { value = scb.Color; } return(value); }
private object EnsurePropertyType(object item, Type targetType) { if (targetType == null || item == null) { return(item); } Type itemType = item.GetType(); if (targetType.IsAssignableFrom(itemType)) { return(item); } else if (itemType == typeof(string) && TypeFromStringConverters.CanTypeBeConverted(targetType)) { return(TypeFromStringConverters.ConvertFromInvariantString(targetType, (string)item)); } else { //note: can crash return(Convert.ChangeType(item, targetType)); } }
internal void UpdateSourceObject(object value) { if (!PropertyPathWalker.IsPathBroken) { PropertyPathNode node = (PropertyPathNode)PropertyPathWalker.FinalNode; bool oldIsUpdating = IsUpdating; try { Type expectedType = null; object convertedValue = value; if (ParentBinding.Converter != null) { if (node.DependencyProperty != null) { #if MIGRATION convertedValue = ParentBinding.Converter.ConvertBack(value, node.DependencyProperty.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture); #else convertedValue = ParentBinding.Converter.ConvertBack(value, node.DependencyProperty.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage); #endif expectedType = node.DependencyProperty.PropertyType; } else if (node.PropertyInfo != null) { #if MIGRATION convertedValue = ParentBinding.Converter.ConvertBack(value, node.PropertyInfo.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture); #else convertedValue = ParentBinding.Converter.ConvertBack(value, node.PropertyInfo.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage); #endif expectedType = node.PropertyInfo.PropertyType; } else if (node.FieldInfo != null) { #if MIGRATION convertedValue = ParentBinding.Converter.ConvertBack(value, node.FieldInfo.FieldType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture); #else convertedValue = ParentBinding.Converter.ConvertBack(value, node.FieldInfo.FieldType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage); #endif expectedType = node.FieldInfo.FieldType; } } else //we only need to set expectedType: { if (node.DependencyProperty != null) { expectedType = node.DependencyProperty.PropertyType; } else if (node.PropertyInfo != null) { expectedType = node.PropertyInfo.PropertyType; } else if (node.FieldInfo != null) { expectedType = node.FieldInfo.FieldType; } } bool typeAcceptsNullAsValue = !expectedType.IsValueType || expectedType.FullName.StartsWith("System.Nullable`1"); bool isNotNullOrIsNullAccepted = ((convertedValue != null) || typeAcceptsNullAsValue); if (isNotNullOrIsNullAccepted) //Note: we put this test here to avoid making unneccessary tests but the point is that the new value is simply ignored since it doesn't fit the property (cannot set a non-nullable property to null). { //bool oldIsUpdating = IsUpdating; IsUpdating = true; Type[] AutoConvertTypes = { typeof(Int16), typeof(Int32), typeof(Int64), typeof(Double), typeof(Uri) }; bool typeFound = false; if ((AutoConvertTypes.Contains(expectedType)) && convertedValue is string) //todo: find a way to do this more efficiently (and maybe mode generic ?) { typeFound = true; if (expectedType == typeof(Int16)) { convertedValue = Int16.Parse((string)convertedValue); } else if (expectedType == typeof(Int32)) { convertedValue = Int32.Parse((string)convertedValue); } else if (expectedType == typeof(Int64)) { convertedValue = Int64.Parse((string)convertedValue); } else if (expectedType == typeof(Double)) { convertedValue = Double.Parse((string)convertedValue); } else if (expectedType == typeof(Uri)) { convertedValue = new Uri((string)convertedValue); } } //todo: partially merge this "if" and the previous one. if ((!typeFound && TypeFromStringConverters.CanTypeBeConverted(expectedType)) && convertedValue is string) { typeFound = true; convertedValue = TypeFromStringConverters.ConvertFromInvariantString(expectedType, (string)convertedValue); } if (!typeFound && convertedValue != null && (expectedType == typeof(string))) { convertedValue = convertedValue.ToString(); } node.SetValue(convertedValue); Validation.ClearInvalid(this); } } catch (Exception e) { //If we have ValidatesOnExceptions set to true, we display a popup with the error close to the element. if (ParentBinding.ValidatesOnExceptions) { //We get the new Error (which is the innermost exception as far as I know): Exception currentException = e; if (Interop.IsRunningInTheSimulator) // Note: "InnerException" is only supported in the Simulator as of July 27, 2017. { while (currentException.InnerException != null) { currentException = currentException.InnerException; } } Validation.MarkInvalid(this, new ValidationError(this) { Exception = currentException, ErrorContent = currentException.Message }); } } finally { IsUpdating = oldIsUpdating; } } }