/// <summary> /// Connects Source and Target objects. /// </summary> public void Bind() { // Resolve binding mode and search converter if need if (needAdapterAnyway) { if (adapter == null) { adapter = settings.GetAdapterFor(target.GetType()); } realMode = mode == BindingMode.Default ? adapter.DefaultMode : mode; } else { realMode = mode == BindingMode.Default ? BindingMode.TwoWay : mode; if (realMode == BindingMode.TwoWay || realMode == BindingMode.OneWayToSource) { if (!(target is INotifyPropertyChanged)) { if (adapter == null) { adapter = settings.GetAdapterFor(target.GetType()); } } } } // Get properties info and check if they are collections sourcePropertyInfo = source.GetType( ).GetProperty(sourceProperty); if (null == adapter) { targetPropertyInfo = target.GetType( ).GetProperty(targetProperty); } Type targetPropertyClass = (null == adapter) ? targetPropertyInfo.PropertyType : adapter.GetTargetPropertyClazz(targetProperty); sourceIsObservable = typeof(IObservableList).IsAssignableFrom(sourcePropertyInfo.PropertyType); targetIsObservable = typeof(IObservableList).IsAssignableFrom(targetPropertyClass); // We need converter if data will flow from non-observable property to property of another class if (targetPropertyClass != sourcePropertyInfo.PropertyType) { bool needConverter = false; if (realMode == BindingMode.OneTime || realMode == BindingMode.OneWay || realMode == BindingMode.TwoWay) { needConverter |= !sourceIsObservable; } if (realMode == BindingMode.OneWayToSource || realMode == BindingMode.TwoWay) { needConverter |= !targetIsObservable; } // if (needConverter) { if (converter == null) { converter = settings.GetConverterFor(targetPropertyClass, sourcePropertyInfo.PropertyType); } else { // Check if converter must be reversed if (converter.FirstType.IsAssignableFrom(targetPropertyClass) && converter.SecondType.IsAssignableFrom(sourcePropertyInfo.PropertyType)) { // Nothing to do, it's ok } else if (converter.SecondType.IsAssignableFrom(targetPropertyClass) && converter.FirstType.IsAssignableFrom(sourcePropertyInfo.PropertyType)) { // Should be reversed converter = new ReversedConverter(converter); } else { throw new Exception("Provided converter doesn't support conversion between " + "specified properties."); } } if (converter == null) { throw new Exception(String.Format("Converter for {0} -> {1} classes not found.", targetPropertyClass.Name, sourcePropertyInfo.PropertyType.Name)); } } } // Verify properties getters and setters for specified binding mode if (realMode == BindingMode.OneTime || realMode == BindingMode.OneWay || realMode == BindingMode.TwoWay) { if (sourcePropertyInfo.GetGetMethod() == null) { throw new Exception("Source property getter not found"); } if (sourceIsObservable) { if (null == adapter && targetPropertyInfo.GetGetMethod() == null) { throw new Exception("Target property getter not found"); } if (!typeof(IList).IsAssignableFrom(targetPropertyClass)) { throw new Exception("Target property class have to implement IList"); } } else { if (null == adapter && targetPropertyInfo.GetSetMethod() == null) { throw new Exception("Target property setter not found"); } } } if (realMode == BindingMode.OneWayToSource || realMode == BindingMode.TwoWay) { if (null == adapter && targetPropertyInfo.GetGetMethod() == null) { throw new Exception("Target property getter not found"); } if (targetIsObservable) { if (sourcePropertyInfo.GetGetMethod() == null) { throw new Exception("Source property getter not found"); } if (!typeof(IList).IsAssignableFrom(sourcePropertyInfo.PropertyType)) { throw new Exception("Source property class have to implement IList"); } } else { if (sourcePropertyInfo.GetSetMethod() == null) { throw new Exception("Source property setter not found"); } } } // Subscribe to listeners ConnectSourceAndTarget(); // Initial flush values if (realMode == BindingMode.OneTime || realMode == BindingMode.OneWay || realMode == BindingMode.TwoWay) { UpdateTarget(); } if (realMode == BindingMode.OneWayToSource || realMode == BindingMode.TwoWay) { UpdateSource(); } this.bound = true; }