/// <summary> /// Attempts to find the dependency or attached property with the specified name. /// </summary> /// <param name="state">The expression compiler's current state.</param> /// <param name="name">The name of the dependency or attached property to retrieve.</param> /// <param name="ownerType">The type that references the dependency or attached property.</param> /// <returns>The <see cref="DependencyProperty"/> referred to by the specified name, or <see langword="null"/> if there is no such dependency property.</returns> private static DependencyProperty FindDependencyOrAttachedPropertyByName(IExpressionCompilerState state, String name, Type ownerType) { if (ExpressionUtil.IsAttachedProperty(name, out var container, out var property)) { if (!state.GetKnownType(container, out var containerType)) return null; return DependencyProperty.FindByName(property, containerType); } return DependencyProperty.FindByName(name, ownerType); }
/// <summary> /// Performs initialization required by instances of the <see cref="ContentPresenter"/> class. /// </summary> private void InitializeContentPresenter(UltravioletContext uv, Object instance, UvmlInstantiationContext context) { var contentPresenter = instance as ContentPresenter; if (contentPresenter == null) { return; } if (contentPresenter.HasDefinedValue(ContentPresenter.ContentProperty) || contentPresenter.TemplatedParent == null) { return; } var alias = contentPresenter.ContentSource ?? "Content"; if (alias == String.Empty) { return; } var templateType = contentPresenter.TemplatedParent.GetType(); var templateWrapperName = PresentationFoundationView.GetDataSourceWrapperNameForComponentTemplate(templateType); var templateWrapperType = uv.GetUI().GetPresentationFoundation().GetDataSourceWrapperTypeByName(templateWrapperName); var dpAliasedContent = DependencyProperty.FindByName(alias, templateType); if (dpAliasedContent != null) { contentPresenter.BindValue(ContentPresenter.ContentProperty, templateWrapperType, "{{" + dpAliasedContent.Name + "}}"); } if (!contentPresenter.HasDefinedValue(ContentPresenter.ContentStringFormatProperty)) { var dpAliasedContentStringFormat = DependencyProperty.FindByName(alias + "StringFormat", templateType); if (dpAliasedContentStringFormat != null) { contentPresenter.BindValue(ContentPresenter.ContentStringFormatProperty, templateWrapperType, "{{" + dpAliasedContentStringFormat.Name + "}}"); } } }
/// <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("}"); }