public PropertyDetails(AvaloniaObject o, AvaloniaProperty property) { Name = property.IsAttached ? $"[{property.OwnerType.Name}.{property.Name}]" : property.Name; IsAttached = property.IsAttached; // TODO: Unsubscribe when view model is deactivated. o.GetObservable(property).Subscribe(x => { var diagnostic = o.GetDiagnostic(property); Value = diagnostic.Value ?? "(null)"; Priority = (diagnostic.Priority != BindingPriority.Unset) ? diagnostic.Priority.ToString() : diagnostic.Property.Inherits ? "Inherited" : "Unset"; Diagnostic = diagnostic.Diagnostic; }); }
public PropertyDetails(AvaloniaObject o, AvaloniaProperty property) { Name = property.IsAttached ? $"[{property.OwnerType.Name}.{property.Name}]" : property.Name; IsAttached = property.IsAttached; // TODO: Unsubscribe when view model is deactivated. o.GetObservable(property).Subscribe(x => { var diagnostic = o.GetDiagnostic(property); Value = diagnostic.Value ?? "(null)"; Priority = (diagnostic.Priority != BindingPriority.Unset) ? diagnostic.Priority.ToString() : diagnostic.Property.Inherits ? "Inherited" : "Unset"; Diagnostic = diagnostic.Diagnostic; }); }
public PropertyDetails(AvaloniaObject o, AvaloniaProperty property) { _target = o; _property = property; Name = property.IsAttached ? $"[{property.OwnerType.Name}.{property.Name}]" : property.Name; UpdateGroup(); // TODO: Unsubscribe when view model is deactivated. o.GetObservable(property).Subscribe(x => { var diagnostic = o.GetDiagnostic(property); RaiseAndSetIfChanged(ref _value, diagnostic.Value); Priority = (diagnostic.Priority != BindingPriority.Unset) ? diagnostic.Priority.ToString() : diagnostic.Property.Inherits ? "Inherited" : "Unset"; Diagnostic = diagnostic.Diagnostic; }); }
private void AddBinding <T>(string modelFieldName, AvaloniaObject control, AvaloniaProperty <T> property, bool isTwoWayDataBinding = false) { // (ideas from here)[http://avaloniaui.net/docs/binding/binding-from-code] var bindingSource = new Subject <T>(); control.Bind <T>(property, bindingSource.AsObservable()); bool bindingIsDataContext = false; object dataContext = null; // does model contain a datacontext??? if (this.Model.HasKey(SpecialModelKeys.DataContext)) { // bind to the data context dataContext = this.Model[SpecialModelKeys.DataContext]; if (dataContext is System.ComponentModel.INotifyPropertyChanged prop) { // It's INotifyPropertyChanged so set this as handled bindingIsDataContext = true; // need to fire it's current value. Then start watching for changes var currentValue = getDataContextValue(dataContext, modelFieldName); log.Debug( $"AddBinding-Model Value Change [*Initial* Field: {modelFieldName}; New Value: {currentValue}]"); FireOnNextWithValue <T>(bindingSource, currentValue); prop.PropertyChanged += (_s, _args) => { if (string.Equals(_args.PropertyName, modelFieldName, StringComparison.OrdinalIgnoreCase)) { var newCurrentValue = getDataContextValue(dataContext, modelFieldName); log.Debug($"AddBinding-Model Value Change [Field: {modelFieldName}; New Value: {newCurrentValue}]"); FireOnNextWithValue <T>(bindingSource, newCurrentValue); } }; } else { /* * !!REMEMBER!! You can use the bindabledictionary * If you don't want to go to the trouble of implementing INotifyPropertyChanged just have your items use BindableDictionary and it's pretty easy */ throw new Exception( $"Special DataContext used in model, but DataContext is not INotifyPropertyChanged. [modelFileName: {modelFieldName}] Type given is {dataContext?.GetType().Name ?? "null"}. There is no way to read properties without INotifyPropertyChanged"); } } if (!bindingIsDataContext) { notifyOnModelChange(modelFieldName, (val) => { FireOnNext <T>(bindingSource, modelFieldName); }); } // If they say two way then we setup a watch on the property observable and apply the values back to the model if (isTwoWayDataBinding) { // monitor for Property changes on control var controlValueChangesObservable = control.GetObservable(property); controlValueChangesObservable.Subscribe(newVal => { if (newVal == null) { // there is never a situation where the UI would need to make a model property null right??? return; } log.Debug($"AddBinding-TwoWay-Control Value Change [Control Property: {property.Name}; Field: {modelFieldName}; New Value: {newVal}]"); setModelValue(modelFieldName, newVal); }); } // end of AddBinding }