예제 #1
0
        protected override void OnExecute(XenMessageContext ctx)
        {
            if (ctx.Request == null)
            {
                return;
            }

            var req = ctx.Get <GetObjectRequest>();

            if (req == null)
            {
                return;
            }

            var props = GetXenProperties(req.WidgetId, true, req.Path);

            if (!props.Any())
            {
                return;
            }

            var prop = props[0];

            if (prop.XenType.Descriptor.HasFlag(XenPropertyDescriptors.Enumerable))
            {
                if (prop.XenType.Descriptor.HasFlag(XenPropertyDescriptors.Enumerable))
                {
                    // grab index value; if null, return without creating an ObjectResponse.
                    var index = ReflectionMethods.GetIndexerValue(req.Path[0]);
                    if (index == null)
                    {
                        return;
                    }

                    var item = ReflectionMethods.GetItem(prop.Value, index.Value);
                    prop.Value = GetXenProperties(item);
                }
            }

            prop.Path = req.Path?.Union(prop.Path)?.ToArray();
            var cantCast = SetPath(prop.Value, req.Path);

            ctx.SetResponse <ObjectResponse>(res =>
            {
                res.UnknownCondition = cantCast;
                res.Property         = prop;
                res.WidgetId         = req.WidgetId;
                res.ObjectName       = XenProperty.GetLastPath(req.Path);
            });
        }
예제 #2
0
        protected void SetPropertyValue(string rWidgetId, string[] rPath, object rValue, bool rIsBase64, bool rIsAttachedProperty)
        {
            var ignoreSet      = false;
            var targetPropName = XenProperty.GetLastPath(rPath);
            var pair           = Surface[rWidgetId];

            AttachedPropertyInfo  targetAttachedProp = null;
            XenReflectionProperty targetProp;

            if (rIsAttachedProperty)
            {
                var apAncestors = ElementHelper.GetParents(pair.XenWidget);
                var apInfos     = new List <AttachedPropertyInfo>();

                foreach (var ancestor in apAncestors)
                {
                    var aView = Surface[ancestor.Id];
                    if (aView == null)
                    {
                        continue;
                    }
                    apInfos.AddRange(ElementHelper.GetAttachedProperties(aView.VisualElement));
                }

                if (apInfos.Count == 0)
                {
                    return;
                }
                targetAttachedProp = apInfos.LastOrDefault(a => a.PropertyName == targetPropName);
                if (targetAttachedProp == null)
                {
                    return;
                }

                object apParent      = null;
                object apGrandParent = null;

                if (apAncestors.ElementAtOrDefault(0) != null)
                {
                    apParent = Surface[apAncestors[0].Id].VisualElement;
                }

                if (apAncestors.ElementAtOrDefault(1) != null)
                {
                    apGrandParent = Surface[apAncestors[1].Id].VisualElement;
                }

                targetProp = targetAttachedProp.Convert(apParent, apGrandParent);
            }
            else
            {
                targetProp = pair?
                             .VisualElement?
                             .GetXenRefProperties(rPath)
                             .FirstOrDefault();

                if (targetProp == null)
                {
                    return;
                }
            }

            if (targetPropName != null && targetPropName.Contains("Color"))
            {
                rValue = Color.FromHex(rValue.ToString());
            }

            // todo: make into a serializer
            if (targetPropName != null && targetPropName.Contains("Source"))
            {
                if (!rIsBase64)
                {
                    return;
                }
                var bytes = Convert.FromBase64String(rValue.ToString());

                var src = new XenImageSource(ImageSource.FromStream(() => new MemoryStream(bytes)))
                {
                    FileName = _req.Metadata?.ToString()
                };

                rValue = src;
            }

            // get enumeration value
            if (targetProp.IsTargetEnum)
            {
                var eval = ReflectionMethods.CreateEnum(targetProp.TargetType, rValue);

                if (eval == null)
                {
                    ignoreSet = true;
                }
                else
                {
                    rValue = eval;
                }
            }

            if (!ignoreSet)
            {
                DesignThread.Invoke(() =>
                {
                    // if target property is part of a structure and we're modifying its properties
                    // 1) make a copy of the current value
                    // 2) change the property value
                    // 3) reassign it
                    if (ReflectionMethods.IsValueType(targetProp.ParentObject))
                    {
                        var childProp = targetProp
                                        .ParentObject
                                        .GetXenRefProperties()
                                        .FirstOrDefault(p => p.TargetName == targetPropName);

                        childProp?.SetTargetObject(rValue);
                        var copy = childProp?.ParentObject;

                        var parentInfo = targetProp
                                         .GrandParentObject?
                                         .GetType()
                                         .GetProperty(targetProp.ParentName);

                        parentInfo?.SetValue(targetProp.GrandParentObject, copy);

                        // supporting View -> Struct -> Struct -> Target (valuetype or ref)
                        if (ReflectionMethods.IsValueType(targetProp.GrandParentObject))
                        {
                            if (rPath.Length == 3)
                            {
                                targetProp
                                .GrandParentObject?
                                .GetType()
                                .GetProperty(targetProp.ParentName)
                                .SetValue(targetProp.GrandParentObject, targetProp.ParentObject);

                                pair.VisualElement
                                .GetType()
                                .GetProperty(rPath[0])
                                .SetValue(pair.VisualElement, targetProp.GrandParentObject);
                            }
                        }
                    }
                    // this is assinging a field
                    else if (targetProp.IsTargetStruct && rValue is string)
                    {
                        var fieldName = rValue.ToString() ?? string.Empty;
                        var fieldInfo = targetProp.TargetType.GetStaticFields().FirstOrDefault(f => f.Name == fieldName);

                        if (fieldInfo == null)
                        {
                            if (rIsAttachedProperty)
                            {
                                SetAttachedProperty(rValue, targetAttachedProp, pair);
                            }
                            else
                            {
                                targetProp.SetTargetObject(rValue);
                            }
                        }
                        else
                        {
                            var copy = fieldInfo.GetValue(null);

                            if (rIsAttachedProperty)
                            {
                                SetAttachedProperty(copy, targetAttachedProp, pair);
                            }
                            else
                            {
                                targetProp.SetTargetObject(copy);
                            }
                        }
                    }
                    else
                    {
                        // one last attempt
                        if (rIsAttachedProperty)
                        {
                            SetAttachedProperty(rValue, targetAttachedProp, pair);
                        }
                        else
                        {
                            targetProp.SetTargetObject(rValue);
                        }
                    }
                });
            }
        }