internal virtual void HandleBoundPropertyChanged(ModelBinding binding, ModelPropertyChangedEventArgs e, bool pushToSource) { object convertedValue = e.NewValue; if (binding.Converter != null && binding.Converter.ConvertBack(ref convertedValue) != null) { return; } if (pushToSource) { SynchronizeValue(binding.Source, binding.SourceProperty, convertedValue); } if (binding.Converter != null && binding.Converter.Convert(ref convertedValue) == null && !Equals(convertedValue, e.NewValue) && !ArrayEquals(convertedValue, e.NewValue)) { SynchronizeValue(this, e.Property, convertedValue); if (!String.IsNullOrEmpty(e.Property.PropertyName)) { var action = new Action(() => OnPropertyChanged(new PropertyChangedEventArgs(e.Property.PropertyName))); if (System.Windows.Application.Current != null && System.Windows.Application.Current.Dispatcher != null) { System.Windows.Application.Current.Dispatcher.BeginInvoke(action); } else { action(); } } } }
internal virtual void RefreshBinding(int localPropertyKey, ModelBinding binding) { object value; if (binding.TryPullValue(out value)) { SynchronizeValue(this, ModelProperty.GetPropertyForKey(localPropertyKey), value); } }
internal override void HandleBoundPropertyChanged(ModelBinding binding, ModelPropertyChangedEventArgs e, bool pushToSource) { var value = e.NewValue; // first, validate against the view model string errorMessage = Validate(e.Property, value); if (String.IsNullOrEmpty(errorMessage) && binding.Mode != ModelBindingMode.OneWay) { // then validate the value can be coerced into the source model if (binding.Converter != null) { errorMessage = binding.Converter.ConvertBack(ref value); } if (String.IsNullOrEmpty(errorMessage)) { // finally, validate against the field metadata var fieldMetadata = GetFieldMetadata(binding.Source.GetType(), binding.SourceProperty); if (fieldMetadata != null) { try { errorMessage = fieldMetadata.Validate(binding.Source, value); } catch (InvalidCastException) { // TODO: may need to run database converter } } } } if (!String.IsNullOrEmpty(errorMessage)) { SetError(e.Property, FormatErrorMessage(errorMessage)); } else { SetError(e.Property, null); base.HandleBoundPropertyChanged(binding, e, pushToSource); } }
internal override void RefreshBinding(int localPropertyKey, ModelBinding binding) { var property = ModelProperty.GetPropertyForKey(localPropertyKey); string error; object value = binding.PullValue(out error); if (!String.IsNullOrEmpty(error)) { SetError(property, error); } else { error = Validate(property, value); SetError(property, error); SynchronizeValue(this, property, value); } }
/// <summary> /// Binds a property on a model to the view model. /// </summary> /// <param name="viewModelProperty">View model property to bind.</param> /// <param name="binding">Information about how the view model property is bound.</param> public void SetBinding(ModelProperty viewModelProperty, ModelBinding binding) { ModelBinding oldBinding; if (_bindings.TryGetValue(viewModelProperty.Key, out oldBinding)) { _bindings = _bindings.Remove(viewModelProperty.Key); if (!IsObserving(oldBinding.Source, oldBinding.SourceProperty)) { oldBinding.Source.RemovePropertyChangedHandler(oldBinding.SourceProperty, OnSourcePropertyChanged); } } else if (_selfBindings.TryGetValue(viewModelProperty.Key, out oldBinding)) { _selfBindings = _selfBindings.Remove(viewModelProperty.Key); } if (binding != null) { if (ReferenceEquals(binding.Source, this)) { _selfBindings = _selfBindings.Add(viewModelProperty.Key, binding); RefreshBinding(viewModelProperty.Key, binding); } else { if (!IsObserving(binding.Source, binding.SourceProperty)) { binding.Source.AddPropertyChangedHandler(binding.SourceProperty, OnSourcePropertyChanged); } _bindings = _bindings.Add(viewModelProperty.Key, binding); RefreshBinding(viewModelProperty.Key, binding); } } }