public override void Dispose() { lock (_syncObj) { Detach(); if (_bindingDependency != null) { _bindingDependency.Detach(); _bindingDependency = null; } // Child bindings will be disposed automatically by DependencyObject.Dispose, because they are // added to our binding collection (was done by method AddChild) ResetBindingAttachments(); base.Dispose(); } }
public void Dispose(bool passSourceToContextObject) { Detach(); if (_bindingDependency != null) { _bindingDependency.Detach(); _bindingDependency = null; } ResetChangeHandlerAttachments(); MPF.TryCleanupAndDispose(_valueConverter); object source = Source; if (passSourceToContextObject && source != null) { _contextObject.TakeOverOwnership(source); } else { MPF.TryCleanupAndDispose(source); } base.Dispose(); }
protected bool UpdateBinding() { // Avoid recursive calls: For instance, this can occur when the later call to Evaluate will change our evaluated // source value, which will cause a recursive call to UpdateBinding. if (_isUpdatingBinding) { return(false); } _isUpdatingBinding = true; try { if (KeepBinding) // This is the case if our target descriptor has a binding type { // In this case, this instance should be used rather than the evaluated source value if (_targetDataDescriptor != null) { _contextObject.SetBindingValue(_targetDataDescriptor, this); } _valueAssigned = true; return(true); } IDataDescriptor sourceDd; lock (_syncObj) if (!Evaluate(out sourceDd)) { _valueAssigned = false; return(false); } // We're called multiple times, for example when a resource dictionary changes. // To avoid too many updates, we remember the last updated value. if (ReferenceEquals(sourceDd, _lastUpdatedValue) && !_valueAssigned) { return(true); } _lastUpdatedValue = sourceDd; // Don't lock the following lines because the binding dependency object updates source or target objects. // Holding a lock during that process would offend against the MP2 threading policy. if (_bindingDependency != null) { _bindingDependency.Detach(); } _bindingDependency = null; switch (Mode) { case BindingMode.TwoWay: case BindingMode.OneWayToSource: throw new XamlBindingException( "MultiBindingMarkupExtension doesn't support BindingMode.TwoWay and BindingMode.OneWayToSource"); case BindingMode.OneTime: object value = sourceDd.Value; _contextObject.SetBindingValue(_targetDataDescriptor, value); _valueAssigned = true; Dispose(); return(true); // In this case, we have finished with only assigning the value default: // Mode == BindingMode.OneWay || Mode == BindingMode.Default _bindingDependency = new BindingDependency(sourceDd, _targetDataDescriptor, true, UpdateSourceTrigger.Explicit, null, null, null); _valueAssigned = true; break; } return(true); } finally { _isUpdatingBinding = false; } }
protected virtual bool UpdateBinding() { // Avoid recursive calls: For instance, this can occur when // the later call to Evaluate will change our evaluated source value, which // will cause a recursive call to UpdateBinding. if (_isUpdatingBinding) return false; _isUpdatingBinding = true; try { if (KeepBinding) // This is the case if our target descriptor has a binding type { // In this case, this instance should be used rather than the evaluated source value if (_targetDataDescriptor != null) _contextObject.SetBindingValue(_targetDataDescriptor, this); _valueAssigned = true; return true; } IDataDescriptor sourceDd; if (!Evaluate(out sourceDd)) { _valueAssigned = false; return false; } // We're called multiple times, for example when a resource dictionary changes. // To avoid too many updates, we remember the last updated value. if (ReferenceEquals(sourceDd, _lastUpdatedValue) && !_valueAssigned) return true; _lastUpdatedValue = sourceDd; #if DEBUG_BINDINGS DebugOutput("UpdateBinding: Binding evaluated to '{0}'", sourceDd.Value); #endif if (_bindingDependency != null) _bindingDependency.Detach(); bool attachToSource = false; bool attachToTarget = false; switch (Mode) { case BindingMode.Default: case BindingMode.OneWay: // Currently, we don't really support the Default binding mode in // MediaPortal skin engine. Maybe we will support it in future - // then we'll be able to initialize the mode with a default value // implied by our target data endpoint. attachToSource = true; break; case BindingMode.TwoWay: attachToSource = true; attachToTarget = true; break; case BindingMode.OneWayToSource: attachToTarget = true; break; case BindingMode.OneTime: object value = sourceDd.Value; object convertedValue; if (!Convert(value, _targetDataDescriptor.DataType, out convertedValue)) return false; _contextObject.SetBindingValue(_targetDataDescriptor, ReferenceEquals(value, convertedValue) ? MpfCopyManager.DeepCopyCutLVPs(convertedValue) : convertedValue); _valueAssigned = true; Dispose(true); return true; // In this case, we have finished with only assigning the value } DependencyObject parent; if (UpdateSourceTrigger != UpdateSourceTrigger.LostFocus || !FindAncestor(_contextObject, out parent, FindParentMode.HybridPreferVisualTree, -1, typeof(UIElement))) parent = null; _bindingDependency = new BindingDependency(sourceDd, _targetDataDescriptor, attachToSource, attachToTarget ? UpdateSourceTrigger : UpdateSourceTrigger.Explicit, parent as UIElement, _valueConverter, _converterParameter); _valueAssigned = true; return true; } finally { _isUpdatingBinding = false; } }
public void Dispose(bool passSourceToContextObject) { Detach(); if (_bindingDependency != null) { _bindingDependency.Detach(); _bindingDependency = null; } ResetChangeHandlerAttachments(); MPF.TryCleanupAndDispose(_valueConverter); object source = Source; if (passSourceToContextObject && source != null) _contextObject.TakeOverOwnership(source); else MPF.TryCleanupAndDispose(source); base.Dispose(); }
protected virtual bool UpdateBinding() { // Avoid recursive calls: For instance, this can occur when // the later call to Evaluate will change our evaluated source value, which // will cause a recursive call to UpdateBinding. if (_isUpdatingBinding) { return(false); } _isUpdatingBinding = true; try { if (KeepBinding) // This is the case if our target descriptor has a binding type { // In this case, this instance should be used rather than the evaluated source value if (_targetDataDescriptor != null) { _contextObject.SetBindingValue(_targetDataDescriptor, this); } _valueAssigned = true; return(true); } IDataDescriptor sourceDd; if (!Evaluate(out sourceDd)) { _valueAssigned = false; return(false); } // We're called multiple times, for example when a resource dictionary changes. // To avoid too many updates, we remember the last updated value. if (ReferenceEquals(sourceDd, _lastUpdatedValue) && !_valueAssigned) { return(true); } _lastUpdatedValue = sourceDd; #if DEBUG_BINDINGS DebugOutput("UpdateBinding: Binding evaluated to '{0}'", sourceDd.Value); #endif if (_bindingDependency != null) { _bindingDependency.Detach(); } bool attachToSource = false; bool attachToTarget = false; switch (Mode) { case BindingMode.Default: case BindingMode.OneWay: // Currently, we don't really support the Default binding mode in // MediaPortal skin engine. Maybe we will support it in future - // then we'll be able to initialize the mode with a default value // implied by our target data endpoint. attachToSource = true; break; case BindingMode.TwoWay: attachToSource = true; attachToTarget = true; break; case BindingMode.OneWayToSource: attachToTarget = true; break; case BindingMode.OneTime: object value = sourceDd.Value; object convertedValue; if (!Convert(value, _targetDataDescriptor.DataType, out convertedValue)) { return(false); } _contextObject.SetBindingValue(_targetDataDescriptor, ReferenceEquals(value, convertedValue) ? MpfCopyManager.DeepCopyCutLVPs(convertedValue) : convertedValue); _valueAssigned = true; Dispose(true); return(true); // In this case, we have finished with only assigning the value } DependencyObject parent; if (UpdateSourceTrigger != UpdateSourceTrigger.LostFocus || !FindAncestor(_contextObject, out parent, FindParentMode.HybridPreferVisualTree, -1, typeof(UIElement))) { parent = null; } _bindingDependency = new BindingDependency(sourceDd, _targetDataDescriptor, attachToSource, attachToTarget ? UpdateSourceTrigger : UpdateSourceTrigger.Explicit, parent as UIElement, _valueConverter, _converterParameter); _valueAssigned = true; return(true); } finally { _isUpdatingBinding = false; } }