/// <summary> /// Unbinds this binding /// </summary> public override void Unbind() { base.Unbind(); RemoveEvent(DataValueChangedEvent); InnerBinding.Unbind(); }
public override Task ExecuteBindingAsync( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken ) { return(TraceWriter.TraceBeginEndAsync( actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info, InnerBinding.GetType().Name, ExecuteBindingAsyncMethodName, beginTrace: (tr) => { tr.Message = Error.Format( SRResources.TraceBeginParameterBind, InnerBinding.Descriptor.ParameterName ); }, execute: () => InnerBinding.ExecuteBindingAsync( metadataProvider, actionContext, cancellationToken ), endTrace: (tr) => { string parameterName = InnerBinding.Descriptor.ParameterName; // Model binding error for this parameter shows the error if ( !actionContext.ModelState.IsValid && actionContext.ModelState.ContainsKey(parameterName) ) { tr.Message = Error.Format( SRResources.TraceModelStateInvalidMessage, FormattingUtilities.ModelStateToString(actionContext.ModelState) ); } else { tr.Message = actionContext.ActionArguments.ContainsKey(parameterName) ? Error.Format( SRResources.TraceEndParameterBind, parameterName, FormattingUtilities.ValueToString( actionContext.ActionArguments[parameterName], CultureInfo.CurrentCulture ) ) : Error.Format(SRResources.TraceEndParameterBindNoBind, parameterName); } }, errorTrace: null )); }
/// <summary> /// Provides a values to be used by the framework to set a given target's object target property binding. /// </summary> /// <param name="serviceProvider">Service provider offered by the framework.</param> /// <returns>A <see cref="Binding"/> for the targeted object and property.</returns> public override object ProvideValue(IServiceProvider serviceProvider) { // Format will be: // <MyDependencyObject MyProperty={BoundPathBinding PathValueBinding={Binding somePropertyProvider}} /> // Build binding in base: var result = base.ProvideValue(serviceProvider); // 'Normal' binding is no path is provided: if (PathValueBinding == null) { initialized = true; } // Else try to setup binding from here (else will be redone at init and loading): else if (result is BindingExpression) { // As we won't return it as result to framework, it will be GCed. Keep a copy now: boundPathBinding = InnerBinding?.Clone(); if (boundPathBinding != null) { // Try to init now: providing_value = true; Initialize(serviceProvider); providing_value = false; // If success, then return bound path binding immediately: if (initialized) { return(boundPathBinding.ProvideValue(serviceProvider)); } else // Else return empty binding: { // Build self binding which will be our "null" value to set: selfPropertyBinding = BindingHelpers.GetIdentityBinding(TargetProperty); return(selfPropertyBinding.ProvideValue(serviceProvider)); // and return an empty binding while path is unresolved. } } else { initialized = true; } } return(result); }
/// <summary> /// Hooks up the late bound events for this object /// </summary> protected override void HandleEvent(string handler) { switch (handler) { case DataValueChangedEvent: if (dataValueChangedReference == null) { dataValueChangedReference = InnerBinding.AddValueChangedHandler( DataItem, new EventHandler <EventArgs>(HandleChangedEvent) ); } break; default: base.HandleEvent(handler); break; } }
/// <summary> /// Removes the late bound events for this object /// </summary> protected override void RemoveEvent(string handler) { switch (handler) { case DataValueChangedEvent: if (dataValueChangedReference != null) { InnerBinding.RemoveValueChangedHandler( dataValueChangedReference, new EventHandler <EventArgs>(HandleChangedEvent) ); dataValueChangedReference = null; } break; default: base.RemoveEvent(handler); break; } }