/// <summary> /// Writes a property which wraps a binding expression. /// </summary> /// <param name="state">The expression compiler's current state.</param> /// <param name="dataSourceWrapperInfo">A <see cref="DataSourceWrapperInfo"/> describing the data source for which to write an expression property.</param> /// <param name="expressionInfo">The binding expression for which to write a property.</param> /// <param name="id">The expression's identifier within the view model.</param> public void WriteExpressionProperty(ExpressionCompilerState state, DataSourceWrapperInfo dataSourceWrapperInfo, BindingExpressionInfo expressionInfo, Int32 id) { var isDependencyProperty = false; var isSimpleDependencyProperty = false; var expText = BindingExpressions.GetBindingMemberPathPart(expressionInfo.Expression); var expTarget = default(String); var expTargetType = dataSourceWrapperInfo.DataSourceType; var expFormatString = BindingExpressions.GetBindingFormatStringPart(expressionInfo.Expression); var targeted = GetExpressionTargetInfo(state, dataSourceWrapperInfo, expressionInfo.Source, ref expText, out expTarget, out expTargetType); var dprop = DependencyProperty.FindByName(expText, expTargetType); var dpropField = default(FieldInfo); if (dprop != null) { isDependencyProperty = true; dpropField = (from prop in dprop.OwnerType.GetFields(BindingFlags.Public | BindingFlags.Static) where prop.FieldType == typeof(DependencyProperty) && prop.GetValue(null) == dprop select prop).SingleOrDefault(); if (dpropField == null) { throw new BindingExpressionCompilationErrorException(expressionInfo.Source, dataSourceWrapperInfo.DataSourceDefinition.DefinitionPath, PresentationStrings.CannotFindDependencyPropertyField.Format(dprop.OwnerType.Name, dprop.Name)); } if (String.IsNullOrEmpty(expFormatString) && !targeted) { isSimpleDependencyProperty = true; } } WriteLine("[{0}(@\"{1}\", SimpleDependencyPropertyOwner = {2}, SimpleDependencyPropertyName = {3})]", typeof(CompiledBindingExpressionAttribute).FullName, expressionInfo.Expression.Replace("\"", "\"\""), isSimpleDependencyProperty ? "typeof(" + GetCSharpTypeName(dprop.OwnerType) + ")" : "null", isSimpleDependencyProperty ? "\"" + dprop.Name + "\"" : "null"); WriteLine("public {0} __UPF_Expression{1}", GetCSharpTypeName(expressionInfo.Type), id); WriteLine("{"); if (expressionInfo.GenerateGetter) { expressionInfo.GetterLineStart = LineCount; var getexp = default(String); if (isDependencyProperty) { getexp = String.Format("{0}GetValue<{1}>({2}.{3})", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name); } else { getexp = String.Format("{0}{1}", expTarget, expText); } var hasFormatString = !String.IsNullOrEmpty(expFormatString); expFormatString = hasFormatString ? String.Format("\"{{0:{0}}}\"", expFormatString) : "null"; if (IsStringType(expressionInfo.Type) || (expressionInfo.Type == typeof(Object) && hasFormatString)) { WriteLine("get"); WriteLine("{"); WriteLine("var value = {0};", getexp); WriteLine("return ({0})__UPF_ConvertToString(value, {1});", GetCSharpTypeName(expressionInfo.Type), expFormatString); WriteLine("}"); } else { WriteLine("get {{ return ({0})({1}); }}", GetCSharpTypeName(expressionInfo.Type), getexp); } expressionInfo.GetterLineEnd = LineCount - 1; } if (dprop != null && dprop.IsReadOnly) { expressionInfo.GenerateSetter = false; } if (expressionInfo.GenerateSetter) { var targetTypeName = expressionInfo.CS0266TargetType; var targetTypeSpecified = !String.IsNullOrEmpty(targetTypeName); expressionInfo.SetterLineStart = LineCount; if (isDependencyProperty) { if (IsStringType(expressionInfo.Type)) { WriteLine("set"); WriteLine("{"); WriteLine("var current = {0}GetValue<{1}>({2}.{3});", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name); WriteLine("{0}SetValue<{1}>({2}.{3}, __UPF_ConvertFromString(value.ToString(), current));", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name); WriteLine("}"); } else { if (expressionInfo.NullableFixup) { WriteLine(targetTypeSpecified ? "set {{ {0}SetValue<{1}>({2}.{3}, ({4})(value ?? default({1}))); }}" : "set {{ {0}SetValue<{1}>({2}.{3}, value ?? default({1})); }}", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name, targetTypeName); } else { WriteLine(targetTypeSpecified ? "set {{ {0}SetValue<{1}>({2}.{3}, ({4})(value)); }}" : "set {{ {0}SetValue<{1}>({2}.{3}, value); }}", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name, targetTypeName); } } } else { if (expressionInfo.Type == typeof(String) || expressionInfo.Type == typeof(VersionedStringSource)) { WriteLine("set"); WriteLine("{"); WriteLine("var current = {0}{1};", expTarget, expText); WriteLine("{0}{1} = __UPF_ConvertFromString(value.ToString(), current);", expTarget, expText); WriteLine("}"); } else { if (expressionInfo.NullableFixup) { WriteLine(targetTypeSpecified ? "set {{ {0}{1} = ({3})(value ?? default({2})); }}" : "set {{ {0}{1} = value ?? default({2}); }}", expTarget, expText, GetCSharpTypeName(Nullable.GetUnderlyingType(expressionInfo.Type)), targetTypeName); } else { WriteLine(targetTypeSpecified ? "set {{ {0}{1} = ({2})(value); }}" : "set {{ {0}{1} = value; }}", expTarget, expText, targetTypeName); } } } expressionInfo.SetterLineEnd = LineCount - 1; } WriteLine("}"); }
/// <summary> /// Writes a property which wraps a binding expression. /// </summary> /// <param name="state">The expression compiler's current state.</param> /// <param name="dataSourceWrapperInfo">A <see cref="DataSourceWrapperInfo"/> describing the data source for which to write an expression property.</param> /// <param name="expressionInfo">The binding expression for which to write a property.</param> /// <param name="id">The expression's identifier within the view model.</param> public void WriteExpressionProperty(ExpressionCompilerState state, DataSourceWrapperInfo dataSourceWrapperInfo, BindingExpressionInfo expressionInfo, Int32 id) { var isDependencyProperty = false; var isSimpleDependencyProperty = false; var expText = BindingExpressions.GetBindingMemberPathPart(expressionInfo.Expression); var expTarget = default(String); var expTargetType = dataSourceWrapperInfo.DataSourceType; var expFormatString = BindingExpressions.GetBindingFormatStringPart(expressionInfo.Expression); var targeted = GetExpressionTargetInfo(state, dataSourceWrapperInfo, expressionInfo.Source, ref expText, out expTarget, out expTargetType); var dprop = DependencyProperty.FindByName(expText, expTargetType); var dpropField = default(FieldInfo); if (dprop != null) { isDependencyProperty = true; dpropField = (from prop in dprop.OwnerType.GetFields(BindingFlags.Public | BindingFlags.Static) where prop.FieldType == typeof(DependencyProperty) && prop.GetValue(null) == dprop select prop).SingleOrDefault(); if (dpropField == null) { throw new BindingExpressionCompilationErrorException(expressionInfo.Source, dataSourceWrapperInfo.DataSourceDefinition.DefinitionPath, PresentationStrings.CannotFindDependencyPropertyField.Format(dprop.OwnerType.Name, dprop.Name)); } if (String.IsNullOrEmpty(expFormatString) && !targeted) { isSimpleDependencyProperty = true; } } WriteLine("[{0}(@\"{1}\", SimpleDependencyPropertyOwner = {2}, SimpleDependencyPropertyName = {3})]", typeof(CompiledBindingExpressionAttribute).FullName, expressionInfo.Expression.Replace("\"", "\"\""), isSimpleDependencyProperty ? "typeof(" + GetCSharpTypeName(dprop.OwnerType) + ")" : "null", isSimpleDependencyProperty ? "\"" + dprop.Name + "\"" : "null"); WriteLine("public {0} __UPF_Expression{1}", GetCSharpTypeName(expressionInfo.Type), id); WriteLine("{"); if (expressionInfo.GenerateGetter) { expressionInfo.GetterLineStart = LineCount; var getexp = default(String); if (isDependencyProperty) { getexp = String.Format("{0}GetValue<{1}>({2}.{3})", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name); } else { getexp = String.Format("{0}{1}", expTarget, expText); } var hasFormatString = !String.IsNullOrEmpty(expFormatString); expFormatString = hasFormatString ? String.Format("\"{{0:{0}}}\"", expFormatString) : "null"; if (IsStringType(expressionInfo.Type) || (expressionInfo.Type == typeof(Object) && hasFormatString)) { WriteLine("get"); WriteLine("{"); WriteLine("var value = {0};", getexp); WriteLine("return ({0})__UPF_ConvertToString(value, {1});", GetCSharpTypeName(expressionInfo.Type), expFormatString); WriteLine("}"); } else { WriteLine("get {{ return ({0})({1}); }}", GetCSharpTypeName(expressionInfo.Type), getexp); } expressionInfo.GetterLineEnd = LineCount - 1; } if (dprop != null && dprop.IsReadOnly) expressionInfo.GenerateSetter = false; if (expressionInfo.GenerateSetter) { var targetTypeName = expressionInfo.CS0266TargetType; var targetTypeSpecified = !String.IsNullOrEmpty(targetTypeName); expressionInfo.SetterLineStart = LineCount; if (isDependencyProperty) { if (IsStringType(expressionInfo.Type)) { WriteLine("set"); WriteLine("{"); WriteLine("var current = {0}GetValue<{1}>({2}.{3});", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name); WriteLine("{0}SetValue<{1}>({2}.{3}, __UPF_ConvertFromString(value, current));", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name); WriteLine("}"); } else { if (expressionInfo.NullableFixup) { WriteLine(targetTypeSpecified ? "set {{ {0}SetValue<{1}>({2}.{3}, ({4})(value ?? default({1}))); }}" : "set {{ {0}SetValue<{1}>({2}.{3}, value ?? default({1})); }}", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name, targetTypeName); } else { WriteLine(targetTypeSpecified ? "set {{ {0}SetValue<{1}>({2}.{3}, ({4})(value)); }}" : "set {{ {0}SetValue<{1}>({2}.{3}, value); }}", expTarget, GetCSharpTypeName(dprop.PropertyType), GetCSharpTypeName(dprop.OwnerType), dpropField.Name, targetTypeName); } } } else { if (IsStringType(expressionInfo.Type)) { WriteLine("set"); WriteLine("{"); WriteLine("var current = {0}{1};", expTarget, expText); WriteLine("{0}{1} = __UPF_ConvertFromString(value, current);", expTarget, expText); WriteLine("}"); } else { if (expressionInfo.NullableFixup) { WriteLine(targetTypeSpecified ? "set {{ {0}{1} = ({3})(value ?? default({2})); }}" : "set {{ {0}{1} = value ?? default({2}); }}", expTarget, expText, GetCSharpTypeName(Nullable.GetUnderlyingType(expressionInfo.Type)), targetTypeName); } else { WriteLine(targetTypeSpecified ? "set {{ {0}{1} = ({2})(value); }}" : "set {{ {0}{1} = value; }}", expTarget, expText, targetTypeName); } } } expressionInfo.SetterLineEnd = LineCount - 1; } WriteLine("}"); }