예제 #1
0
        /// <summary>
        /// When overridden in a derived class, sets the value of the component to a different value.
        /// </summary>
        public override void SetValue(object component, object value)
        {
            var stringValue   = value as string;
            var settingsValue = value as IPropertyBindingSettings;

            // The setter will be called with a plain string value whenever the standard values editor is
            // used to pick the TypeId. So we need to actually set that value on the binding instead.
            if (stringValue != null)
            {
                // Note that the setting of the property Value automatically triggers a property changed
                // that will cause the value to be serialized and saved :). Indeed,
                // it will be calling the SetValue again, but this time with the entire binding settings
                // so it will call the next code branch.
                ((IPropertyBindingSettings)this.GetValue(component)).Value = stringValue;
            }
            else if (settingsValue != null)
            {
                // Someone is explicitly setting the entire binding value, so we have to serialize it straight.
                base.SetValue(component, BindingSerializer.Serialize(settingsValue));

                // If the previous value was non-null, then we'd be monitoring its property changes
                // already, and we'd need to unsubscribe.
                if (this.settings != null)
                {
                    this.settings.PropertyChanged -= OnSettingsChanged;
                }

                // Store for reuse on GetValue, and attach to property changes for auto-save.
                this.settings = settingsValue;
                this.settings.PropertyChanged += OnSettingsChanged;
            }
        }
예제 #2
0
        internal static IPropertyBindingSettings EnsurePropertySettings(object component, string propertyName, Type propertyType)
        {
            // This check for the type of component is here because
            // we use the same descriptor for both properties on the
            // condition model as well as on the value provider.
            IPropertyBindingSettings propertySettings = null;
            var settings = component as IBindingSettings;

            if (settings != null)
            {
                propertySettings = settings.Properties.FirstOrDefault(prop => prop.Name == propertyName);
                if (propertySettings == null)
                {
                    propertySettings = CreatePropertySettings(settings, propertyName, propertyType);
                    settings.Properties.Add(propertySettings);
                }
            }
            else
            {
                var design = component as DesignValueProvider;
                if (design != null)
                {
                    propertySettings = design.ValueProvider.Properties.FirstOrDefault(prop => prop.Name == propertyName);
                    if (propertySettings == null)
                    {
                        propertySettings = CreatePropertySettings(design, propertyName, propertyType);
                        design.ValueProvider.Properties.Add(propertySettings);
                    }
                }
            }

            return(propertySettings);
        }
예제 #3
0
        /// <summary>
        /// Resets binding.
        /// </summary>
        public static void Reset(this IPropertyBindingSettings settings)
        {
            Guard.NotNull(() => settings, settings);

            settings.Value         = BindingSettings.Empty;
            settings.ValueProvider = null;
        }
예제 #4
0
        /// <summary>
        /// When overridden in a derived class, gets the current value of the property on a component.
        /// </summary>
        public override object GetValue(object component)
        {
            // We cache the settings to avoid paying the serialization cost too often.
            // Also, this allows us to track changes more consistently.
            if (this.settings == null)
            {
                var json = base.GetValue(component) as string;

                if (string.IsNullOrWhiteSpace(json))
                {
                    this.settings = new PropertyBindingSettings {
                        Name = base.Name
                    };
                    // Save the value right after instantiation, so that
                    // subsequent GetValue gets the same instance and
                    // does not re-create from scratch.
                    SetValue(component, settings);
                }
                else
                {
                    // Deserialize always to the concrete type, as we the serializer needs to
                    // know the type of thing to create.
                    try
                    {
                        this.settings = BindingSerializer.Deserialize <PropertyBindingSettings>(json);
                        // Make sure the settings property name matches the actual descriptor property name.
                        if (this.settings.Name != base.Name)
                        {
                            this.settings.Name = base.Name;
                        }
                    }
                    catch (BindingSerializationException)
                    {
                        // This would happen if the value was a raw value from before we had a binding.
                        // Consider it the property value.
                        settings = new PropertyBindingSettings
                        {
                            Name  = base.Name,
                            Value = json,
                        };

                        // Persist updated value.
                        SetValue(component, settings);
                    }
                }

                // Hookup property changed event, which supports nested changes as well. This
                // allows us to automatically save the serialized json on every property change.
                this.settings.PropertyChanged += OnSettingsChanged;
            }

            // We know that we're always dealing with a concrete type implementation as it's not
            // externally set-able and we always instantiate a PropertyBindingSettings.
            return(new DesignProperty(this.settings)
            {
                Type = base.PropertyType,
                Attributes = this.AttributeArray
            });
        }
예제 #5
0
        /// <summary>
        /// Determines whether the binding has a value configured
        /// </summary>
        public static bool HasValueProvider(this IPropertyBindingSettings settings)
        {
            Guard.NotNull(() => settings, settings);

            return((settings.ValueProvider == null)
                ? false
                : !string.IsNullOrEmpty(settings.ValueProvider.TypeId));
        }
예제 #6
0
        /// <summary>
        /// Creates a new instance of the <see cref="DesignProperty"/> class.
        /// </summary>
        public DesignProperty(IPropertyBindingSettings propertySettings, Type type, Attribute[] attributes)
            : this(propertySettings)
        {
            Guard.NotNull(() => type, type);
            Guard.NotNull(() => attributes, attributes);

            this.Type = type;
            this.Attributes = attributes;
        }
예제 #7
0
        /// <summary>
        /// Creates a new instance of the <see cref="DesignProperty"/> class.
        /// </summary>
        public DesignProperty(IPropertyBindingSettings propertySettings, Type type, Attribute[] attributes)
            : this(propertySettings)
        {
            Guard.NotNull(() => type, type);
            Guard.NotNull(() => attributes, attributes);

            this.Type       = type;
            this.Attributes = attributes;
        }
        /// <summary>
        /// When overridden in a derived class, gets the current value of the property on a component.
        /// </summary>
        public override object GetValue(object component)
        {
            // We cache the settings to avoid paying the serialization cost too often.
            // Also, this allows us to track changes more consistently.
            if (this.settings == null)
            {
                var json = base.GetValue(component) as string;

                if (string.IsNullOrWhiteSpace(json))
                {
                    this.settings = new PropertyBindingSettings { Name = base.Name };
                    // Save the value right after instantiation, so that 
                    // subsequent GetValue gets the same instance and 
                    // does not re-create from scratch.
                    SetValue(component, settings);
                }
                else
                {
                    // Deserialize always to the concrete type, as we the serializer needs to 
                    // know the type of thing to create.
                    try
                    {
                        this.settings = BindingSerializer.Deserialize<PropertyBindingSettings>(json);
                        // Make sure the settings property name matches the actual descriptor property name.
                        if (this.settings.Name != base.Name)
                            this.settings.Name = base.Name;
                    }
                    catch (BindingSerializationException)
                    {
                        // This would happen if the value was a raw value from before we had a binding.
                        // Consider it the property value.
                        settings = new PropertyBindingSettings
                        {
                            Name = base.Name,
                            Value = json,
                        };

                        // Persist updated value.
                        SetValue(component, settings);
                    }
                }

                // Hookup property changed event, which supports nested changes as well. This 
                // allows us to automatically save the serialized json on every property change.
                this.settings.PropertyChanged += OnSettingsChanged;
            }

            // We know that we're always dealing with a concrete type implementation as it's not 
            // externally set-able and we always instantiate a PropertyBindingSettings.
            return new DesignProperty(this.settings)
            {
                Type = base.PropertyType,
                Attributes = this.AttributeArray
            };
        }
 public void InitializeContext()
 {
     this.settings = new PropertyBindingSettings
     {
         Value         = "Foo",
         ValueProvider = new ValueProviderBindingSettings
         {
             TypeId = "Bar",
         },
     };
 }
 public void InitializeContext()
 {
     this.settings = new PropertyBindingSettings
     {
         Value = "Foo",
         ValueProvider = new ValueProviderBindingSettings
         {
             TypeId = "Bar",
         },
     };
 }
예제 #11
0
        /// <summary>
        /// Creates a new instance of the <see cref="DesignProperty"/> class.
        /// </summary>
        public DesignProperty(IPropertyBindingSettings propertySettings)
        {
            Guard.NotNull(() => propertySettings, propertySettings);

            this.Settings       = propertySettings;
            this.ValueConverter = new Lazy <TypeConverter>(() =>
            {
                var converter = this.Attributes.FindCustomTypeConverter();
                if (converter == null ||
                    // The custom converter must be capable of converting to AND from string
                    // for proper interaction with the property grid.
                    !converter.CanConvertFrom(typeof(string)) ||
                    !converter.CanConvertTo(typeof(string)))
                {
                    converter = TypeDescriptor.GetConverter(this.Type);
                }

                return(converter);
            });
        }
예제 #12
0
        /// <summary>
        /// Creates a new instance of the <see cref="DesignProperty"/> class.
        /// </summary>
        public DesignProperty(IPropertyBindingSettings propertySettings)
        {
            Guard.NotNull(() => propertySettings, propertySettings);

            this.Settings = propertySettings;
            this.ValueConverter = new Lazy<TypeConverter>(() =>
            {
                var converter = this.Attributes.FindCustomTypeConverter();
                if (converter == null ||
                    // The custom converter must be capable of converting to AND from string 
                    // for proper interaction with the property grid.
                    !converter.CanConvertFrom(typeof(string)) ||
                    !converter.CanConvertTo(typeof(string)))
                {
                    converter = TypeDescriptor.GetConverter(this.Type);
                }

                return converter;
            });
        }
예제 #13
0
        public static string Evaluate(this IPropertyBindingSettings settings, IBindingFactory bindingFactory, ITracer tracer, Action <IDynamicBindingContext> contextInitializer = null)
        {
            string result;

            if (settings.ValueProvider != null)
            {
                var binding = bindingFactory.CreateBinding <IValueProvider>(settings.ValueProvider);
                // Make the entire set of element interfaces available to VP bindings.
                // We add the owner with its full interfaces. And we add the IProperty as well.
                using (var context = binding.CreateDynamicContext())
                {
                    if (contextInitializer != null)
                    {
                        contextInitializer(context);
                    }

                    if (binding.Evaluate(context))
                    {
                        result = binding.Value.Evaluate() as string;
                    }
                    else
                    {
                        var failMessage = string.Format(CultureInfo.CurrentCulture,
                                                        Resources.ValueProviderBinding_FailedToEvaluate,
                                                        settings.Name,
                                                        settings.Name,
                                                        ObjectDumper.ToString(binding.EvaluationResults, 5));

                        tracer.Error(failMessage);

                        throw new InvalidOperationException(failMessage);
                    }
                }
            }
            else
            {
                result = settings.Value;
            }

            return(result);
        }
예제 #14
0
        private IPropertyBindingSettings CreateSettings()
        {
            IPropertyBindingSettings settings;

            if (string.IsNullOrEmpty(getValue()))
            {
                settings = new PropertyBindingSettings
                {
                    Name          = this.propertyName,
                    Value         = BindingSettings.Empty,
                    ValueProvider = null,
                };
            }
            else
            {
                // Be backwards compatible to ease migration.
                try
                {
                    settings = BindingSerializer.Deserialize <PropertyBindingSettings>(getValue());
                }
                catch (BindingSerializationException)
                {
                    // This would happen if the value was a raw value from before we had a binding.
                    // Consider it the property value.
                    settings = new PropertyBindingSettings
                    {
                        Name  = this.propertyName,
                        Value = this.getValue(),
                    };

                    // Persist updated value.
                    this.setValue(BindingSerializer.Serialize(settings));
                }
            }

            // Automatically serialize whenever something is changed in the binding.
            settings.PropertyChanged += OnSettingsChanged;

            return(settings);
        }
예제 #15
0
        private IPropertyBindingSettings CreateSettings()
        {
            IPropertyBindingSettings settings;

            if (string.IsNullOrEmpty(getValue()))
            {
                settings = new PropertyBindingSettings
                {
                    Name = this.propertyName,
                    Value = BindingSettings.Empty,
                    ValueProvider = null,
                };
            }
            else
            {
                // Be backwards compatible to ease migration.
                try
                {
                    settings = BindingSerializer.Deserialize<PropertyBindingSettings>(getValue());
                }
                catch (BindingSerializationException)
                {
                    // This would happen if the value was a raw value from before we had a binding.
                    // Consider it the property value.
                    settings = new PropertyBindingSettings
                    {
                        Name = this.propertyName,
                        Value = this.getValue(),
                    };

                    // Persist updated value.
                    this.setValue(BindingSerializer.Serialize(settings));
                }
            }

            // Automatically serialize whenever something is changed in the binding.
            settings.PropertyChanged += OnSettingsChanged;

            return settings;
        }
        /// <summary>
        /// When overridden in a derived class, sets the value of the component to a different value.
        /// </summary>
        public override void SetValue(object component, object value)
        {
            var stringValue = value as string;
            var settingsValue = value as IPropertyBindingSettings;

            // The setter will be called with a plain string value whenever the standard values editor is 
            // used to pick the TypeId. So we need to actually set that value on the binding instead.
            if (stringValue != null)
            {
                // Note that the setting of the property Value automatically triggers a property changed 
                // that will cause the value to be serialized and saved :). Indeed, 
                // it will be calling the SetValue again, but this time with the entire binding settings
                // so it will call the next code branch.
                ((IPropertyBindingSettings)this.GetValue(component)).Value = stringValue;
            }
            else if (settingsValue != null)
            {
                // Someone is explicitly setting the entire binding value, so we have to serialize it straight.
                base.SetValue(component, BindingSerializer.Serialize(settingsValue));

                // If the previous value was non-null, then we'd be monitoring its property changes 
                // already, and we'd need to unsubscribe.
                if (this.settings != null)
                {
                    this.settings.PropertyChanged -= OnSettingsChanged;
                }

                // Store for reuse on GetValue, and attach to property changes for auto-save.
                this.settings = settingsValue;
                this.settings.PropertyChanged += OnSettingsChanged;
            }
        }
예제 #17
0
        /// <summary>
        /// Determines whether the binding has a value configured
        /// </summary>
        public static bool HasValue(this IPropertyBindingSettings settings)
        {
            Guard.NotNull(() => settings, settings);

            return(!string.IsNullOrEmpty(settings.Value));
        }
예제 #18
0
 /// <summary>
 /// Determines whether the binding is configured with a value or value provider
 /// </summary>
 public static bool IsConfigured(this IPropertyBindingSettings settings)
 {
     return(settings.HasValue() || settings.HasValueProvider());
 }