示例#1
0
#pragma warning restore CA1000 // Do not declare static members on generic types

        #endregion

        #region Internal Static Methods

        internal static object ProvideValue(
            DependencyObject target,
            DependencyProperty property,
            object defaultValue,
            BindingBase xamlBinding)
        {
            if (target == null ||
                property == null)
            {
                return(null);
            }
            object outputValue = defaultValue;

            if (outputValue == null ||
                string.IsNullOrEmpty(outputValue.ToString()))
            {
                throw new InvalidOperationException($@"No default value provided for property ""{target}.{property.Name}""");
            }
            if (!outputValue.GetType().IsSerializable)
            {
                throw new InvalidOperationException($@"Default value provided for property ""{target}.{property.Name}"" is not serializable");
            }

            FrameworkElement visualAnchor = AbstractPropertyState <TState, TElement, TProperty> .GetVisualAnchor(target);

            if (!(target is FrameworkElement element) || visualAnchor != null)
            {
                element = visualAnchor;
            }
            var defaultString = outputValue as string;

            if (!string.IsNullOrEmpty(defaultString))
            {
                outputValue = AbstractPropertyState <TState, TElement, TProperty> .ConvertFromString(target.GetType(), property, defaultString);
            }
            var propertyMultiValueConverter = new PropertyMultiValueConverter()
            {
                Target   = element,
                Property = property,
            };

            void handler(object s, RoutedEventArgs e)
            {
                if (element != null)
                {
                    element.Loaded -= handler;
                }

                if (xamlBinding != null &&
                    !IsPropertyPersisted(target, property))
                {
                    // Normally the persisted state is the initial value used
                    // for an element property when the UI is rendered, but if
                    // no value is persisted (and a data bound property is present)
                    // then use the data bound value.
                    propertyMultiValueConverter.PropertyValuePreference = PropertyValuePreference.DataBound;
                }
                if (!HasPropertyValue(target, property))
                {
                    object value = AddPropertyValue(target, property, outputValue);
                    if (value == null)
                    {
                        throw new InvalidOperationException($@"The element ""{target}"" has no unique identifier for property persistence");
                    }
                }

                var multiBinding = new MultiBinding()
                {
                    Converter           = propertyMultiValueConverter,
                    Mode                = BindingMode.TwoWay,
                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                };

                // Add a new binding between the element property and the
                // persisted state.
                multiBinding.Bindings.Add(CreateStateBinding(target, property));
                if (xamlBinding != null)
                {
                    // If the element property was previously data bound in XAML
                    // then add that binding to the multibinding collection.
                    multiBinding.Bindings.Add(xamlBinding);
                }
                BindingOperations.SetBinding(target, property, multiBinding);

                if (element.IsLoaded)
                {
                    propertyMultiValueConverter.PropertyValuePreference = PropertyValuePreference.DataBound;
                }
            }

            // Windows are already loaded when the application starts
            // so need to invoke their loaded handlers manually.
            if (target is Window)
            {
                handler(null, null);
            }
            // Keep track of the loaded handlers in case they need to
            // activated manually later.
            AddPropertyLoadedHandler(target, property, handler);
            if (element != null)
            {
                element.Loaded += handler;
            }
            if (HasPropertyValue(target, property))
            {
                return(GetPropertyValue(target, property));
            }
            return(outputValue);
        }
示例#2
0
 internal static string GetUidWithNamespace(DependencyObject element)
 {
     return($@"{AbstractPropertyState<TState, TElement, TProperty>.GetNamespace(element)}{AbstractPropertyState<TState, TElement, TProperty>.GetUid(element)}");
 }