File

projects/wms-framework/src/lib/basecomponentmodel/Bindings/Binding.ts

Description

Class for representing compatibility bindings

Index

Properties
Methods

Constructor

constructor(path?: string)

Creates an instance of Binding.

Parameters :
Name Type Optional
path string Yes

Properties

BindsDirectlyToSource
Type : boolean
Default value : false

A flag to determine if this binding binds directly to source

Converter
Type : any
Default value : null

The converter

ConverterCulture
Type : any
Default value : null

Current culture

ConverterParameter
Type : any
Default value : null

The converter parameter

CustomContext
Type : any
Default value : null

Custom context object to use for this binding

ElementInstance
Type : any
Default value : null

Element instane to use as the context of this binding

ElementName
Type : any
Default value : null

Name of the element to use as the context of this binding

inSynchronizing
Default value : false

A flag to determine if the binding is being synchronized

Mode
Type : BindingMode
Default value : BindingMode.OneWay

The mode of this binding

NotifyOnValidationError
Type : boolean
Default value : false

A flag to determine if the notification events need to be triggered on validation events

Path
Type : PropertyPath

The property path of this bnding

RelativeSource
Type : RelativeSourceInfo
Default value : null

Relative source of this binding

Source
Type : unknown

Static resource to use for the context of this binding

StringFormat
Type : string
Default value : null

Format to be applied when the binding displays the value as string.

UpdateSourceTrigger
Type : any
Default value : null

The update source trigger

ValidatesOnDataErrors
Type : boolean
Default value : false

A flag to determine if validation occurs by verifying for data errors

ValidatesOnExceptions
Type : boolean
Default value : false

A flag to determine if validation occurs by verifying in an exception is raised when performing binding updates

ValidatesOnNotifyDataErrors
Type : boolean
Default value : true

A flag to determine if validation occurs by verifying for data errors using INotifyDataErrorInfo

Methods

Public ApplyBinding
ApplyBinding(newValue: any, dataContext: any)

Applies this binding by infering the context and set the new value to the path or property specified by this binding

Parameters :
Name Type Optional Description
newValue any No

the new value to set

dataContext any No

the external data context object used to resolve the binding. It can be null;

Returns : void
Public CalculateRelativeSource
CalculateRelativeSource(model: DependencyObject)

Calculates the relative source (if available)

Parameters :
Name Type Optional
model DependencyObject No
Returns : any

{*}

Private inferContext
inferContext(dataContext: any)

The object to be uses as context to resolve the binding. The order to solve the context is: Source, given dataContext, CustomContext or ElementInstance

Parameters :
Name Type Optional Description
dataContext any No

the external data context object used to resolve the binding, it can be null

Returns : any

the context object use to resolve the binding

Static IsValidBindingContext
IsValidBindingContext(context: any)

Checks if the given context is a valid one or not. A valid context can not be neither undefined nor null.

Parameters :
Name Type Optional Description
context any No

the context to test for

Returns : boolean

true if the context is valid, false otherwise

import { DependencyObject } from '../DependencyObject';
import { Convert } from '../../baseframework/typeconversion';
import { BindingMode } from './BindingMode';
import { PropertyPath } from './PropertyPath';
import { RelativeSourceInfo } from './RelativeSourceInfo';
import { applyStringFormat } from './BindingUtils';

/**
 *  Class for representing compatibility bindings
 *
 * @export
 * @class Binding
 * @wType System.Windows.Data.Binding
 */
export class Binding {
  /**
   * Static resource to use for the context of this binding
   *
   * @type {unknown}
   * @memberof Binding
   */
  Source: unknown;

  /**
   * A flag to determine if this binding
   * binds directly to source
   *
   * @type {boolean}
   * @memberof Binding
   */
  BindsDirectlyToSource: boolean = false;

  /**
   * The converter
   *
   * @type {*}
   * @memberof Binding
   */
  Converter: any = null;

  /**
   * The converter parameter
   *
   * @type {*}
   * @memberof Binding
   */
  ConverterParameter: any = null;

  /**
   * Current culture
   *
   * @type {*}
   * @memberof Binding
   */
  ConverterCulture: any = null;

  /**
   * The mode of this binding
   *
   * @type {BindingMode}
   * @memberof Binding
   */
  Mode: BindingMode = BindingMode.OneWay;

  /**
   * A flag to determine if the notification events
   * need to be triggered on validation events
   *
   * @type {boolean}
   * @memberof Binding
   */
  NotifyOnValidationError: boolean = false;

  /**
   *  The property path of this bnding
   *
   * @type {PropertyPath}
   * @memberof Binding
   */
  Path: PropertyPath;

  /**
   * The update source trigger
   *
   * @type {*}
   * @memberof Binding
   */
  UpdateSourceTrigger: any = null;

  /**
   * A flag to determine if validation occurs by
   * verifying in an exception is raised when performing
   * binding updates
   *
   * @type {boolean}
   * @memberof Binding
   */
  ValidatesOnExceptions: boolean = false;

  /**
   * A flag to determine if validation occurs by
   * verifying for data errors
   *
   * @type {boolean}
   * @memberof Binding
   */
  ValidatesOnDataErrors: boolean = false;

  /**
   * A flag to determine if validation occurs by
   * verifying for data errors using INotifyDataErrorInfo
   *
   * @type {boolean}
   * @memberof Binding
   */
  ValidatesOnNotifyDataErrors: boolean = true;

  /**
   * Name of the element to use as the context of this binding
   *
   * @type {*}
   * @memberof Binding
   */
  ElementName: any = null;

  /**
   * Relative source of this binding
   *
   * @type {*}
   * @memberof Binding
   */
  RelativeSource: RelativeSourceInfo = null;

  /**
   *  Custom context object to use for this binding
   *
   * @type {*}
   * @memberof Binding
   */
  CustomContext: any = null;

  /**
   *  A flag to determine if the binding is being synchronized
   *
   * @memberof Binding
   */
  inSynchronizing = false;

  /**
   * Element instane to use as the context of this binding
   *
   * @type {*}
   * @memberof Binding
   * @wIgnore
   */
  ElementInstance: any = null;

  /**
   * Format to be applied when the binding displays the value as string.
   *
   * @type {string}
   * @memberof Binding
   */
  StringFormat: string = null;

  /**
   * Creates an instance of Binding.
   * @param {string} [path]
   * @memberof Binding
   */
  constructor(path?: string) {
    if (typeof path !== 'undefined') {
      this.Path = new PropertyPath(path);
    } else {
      this.Path = new PropertyPath('');
    }
  }

  /**
   * Checks if the given context is a valid one or not.  A valid context
   * can not be neither undefined nor null.
   * @param context the context to test for
   * @returns true if the context is valid, false otherwise
   * @wIgnore
   */
  public static IsValidBindingContext(context: any) {
    return typeof context !== 'undefined' && context !== null;
  }

  /**
   * Calculates the relative source (if available)
   *
   * @param {DependencyObject} model
   * @return {*}  {*}
   * @memberof Binding
   * @wIgnore
   */
  public CalculateRelativeSource(model: DependencyObject): any {
    if (this.RelativeSource) {
      if (this.RelativeSource.Mode === 'Self') {
        return model;
      } else if (
        this.RelativeSource.Mode === 'FindAncestor' &&
        typeof this.RelativeSource.AncestorType === 'string'
      ) {
        const typeName = this.RelativeSource.AncestorType.replace(/^.*:/, '');
        let currentElement = this.RelativeSource.CustomParent ?? model;
        while (currentElement) {
          if (currentElement.constructor.name === typeName) {
            return currentElement;
          }
          currentElement = currentElement.Parent;
        }
      }
      console.warn('Cannot solve relative source for binding');
    }
    return null;
  }

  /**
   * Applies this binding by infering the context and set the new value to the path or property specified by
   * this binding
   * @param newValue the new value to set
   * @param dataContext  the external data context object used to resolve the binding.  It can be null;
   * @wIgnore
   */
  public ApplyBinding(newValue: any, dataContext: any): void {
    const context = this.inferContext(dataContext);
    if (Binding.IsValidBindingContext(context)) {
      // zero numeric value is valid one
      try {
        const targetPropertyType =
          this.Path.getTypeOfPropertyIfAvailable(context);
        if (this.Converter?.ConvertBack) {
          newValue = this.Converter.ConvertBack(
            newValue,
            targetPropertyType,
            this.ConverterParameter
          );
        }
        newValue = applyStringFormat(this, newValue);

        if (targetPropertyType) {
          newValue = Convert.ChangeType(newValue, targetPropertyType);
        }
        this.inSynchronizing = true;
        this.Path.setValueContextObject(context, newValue);
      } catch (ex) {
        console.log('Unable to set binding value: ' + ex);
        throw ex;
      } finally {
        this.inSynchronizing = false;
      }
    }
  }

  /**
   * The object to be uses as context to resolve the binding.  The order to solve the context is: Source, given dataContext,
   * CustomContext or ElementInstance
   * @param dataContext the external data context object used to resolve the binding, it can be null
   * @returns the context object use to resolve the binding
   */
  private inferContext(dataContext: any): any {
    return (
      this.Source ?? dataContext ?? this.CustomContext ?? this.ElementInstance
    );
  }
}

result-matching ""

    No results matching ""