internal static WeakReference GetNativeObjectWeakReference(NSObject nsObject) { var handle = nsObject.Handle; if (handle == IntPtr.Zero) { return(Empty.WeakReference); } lock (AttachedValueHolders) { AttachedValueHolder value; if (!AttachedValueHolders.TryGetValue(handle, out value)) { value = new AttachedValueHolder(nsObject); AttachedValueHolders[handle] = value; } return(value.WeakReference); } }
protected override LightDictionaryBase <string, object> GetOrAddAttachedDictionary(object item, bool addNew) { var model = item as NotifyPropertyChangedBase; if (model != null) { return(AttachedValueProviderDefault.GetOrAddAttachedValues(model, true)); } #if TOUCH var nsObject = item as NSObject; if (nsObject != null) { var handle = nsObject.Handle; if (handle == IntPtr.Zero) { if (addNew) { Tracer.Error("The object {0} is disposed the attached values cannot be obtained", item.GetType()); return(new AttachedValueDictionary()); } return(null); } AttachedValueHolder holder; lock (AttachedValueHolders) { if (!AttachedValueHolders.TryGetValue(handle, out holder)) { if (!addNew) { return(null); } holder = new AttachedValueHolder(nsObject); AttachedValueHolders[handle] = holder; } } return(holder.GetOrCreateDictionary()); } #elif !WINFORMS && !NET_STANDARD && !ANDROID && !TOUCH && !XAMARIN_FORMS //Synchronization is not necessary because accessing the DependencyObject is possible only from the main thread. var dependencyObject = item as DependencyObject; if (dependencyObject != null) { var dict = (AttachedValueDictionary)dependencyObject.GetValue(AttachedValueDictionaryProperty); if (dict == null && addNew) { dict = new AttachedValueDictionary(); dependencyObject.SetValue(AttachedValueDictionaryProperty, dict); } return(dict); } #elif XAMARIN_FORMS var bindableObject = item as BindableObject; if (bindableObject != null) { var dict = (AttachedValueDictionary)bindableObject.GetValue(AttachedValueDictionaryProperty); if (dict == null && addNew) { lock (_internalDictionary) { dict = (AttachedValueDictionary)bindableObject.GetValue(AttachedValueDictionaryProperty); if (dict == null) { dict = new AttachedValueDictionary(); bindableObject.SetValue(AttachedValueDictionaryProperty, dict); } } } return(dict); } #elif ANDROID if (SetTagSupported) { var view = item as View; if (view.IsAlive()) { var dict = (AttachedValueDictionaryJava)view.GetTag(Resource.Id.AttachedProperties); if (dict == null && addNew) { lock (_internalDictionary) { dict = (AttachedValueDictionaryJava)view.GetTag(Resource.Id.AttachedProperties); if (dict == null) { dict = new AttachedValueDictionaryJava(); view.SetTag(Resource.Id.AttachedProperties, dict); } } } return(dict?.Dictionary); } } //.NET object (Preference) is garbage collected and all attached members too but Java object is still alive. //Save values to activity dictionary. var pref = item as Preference; if (pref.IsAlive() && pref.HasKey) { try { var activityView = pref.Context as IActivityView; if (activityView != null) { var metadata = activityView.Mediator.Metadata; var key = pref.Key + pref.GetType().FullName + pref.GetHashCode(); object v; if (!metadata.TryGetValue(key, out v)) { if (addNew) { v = new AttachedValueDictionary(); metadata[key] = v; } } return((LightDictionaryBase <string, object>)v); } } catch { ; } } #endif if (addNew) { return(_internalDictionary.GetValue(item, CreateDictionaryDelegate)); } AttachedValueDictionary value; _internalDictionary.TryGetValue(item, out value); return(value); }
protected override LightDictionaryBase <string, object> GetOrAddAttachedDictionary(object item, bool addNew) { var handler = GetOrAddAttachedDictionaryHandler?.GetInvocationList(); if (handler != null) { for (int i = 0; i < handler.Length; i++) { var result = ((Func <object, bool, LightDictionaryBase <string, object> >)handler[i]).Invoke(item, addNew); if (result != null) { return(result); } } } var model = item as NotifyPropertyChangedBase; if (model != null) { return(GetOrAddAttachedValues(model, true)); } #if TOUCH var nsObject = item as NSObject; if (nsObject != null) { var handle = nsObject.Handle; if (handle == IntPtr.Zero) { if (addNew) { Tracer.Error("The object {0} is disposed the attached values cannot be obtained", item.GetType()); return(new AttachedValueDictionary()); } return(null); } AttachedValueHolder holder; lock (AttachedValueHolders) { if (!AttachedValueHolders.TryGetValue(handle, out holder)) { if (!addNew) { return(null); } holder = new AttachedValueHolder(nsObject); AttachedValueHolders[handle] = holder; } } return(holder.GetOrCreateDictionary()); } #elif WINDOWS_UWP || WPF || WINFORMS //Synchronization is not necessary because accessing the DependencyObject is possible only from the main thread. var dependencyObject = item as DependencyObject; if (dependencyObject != null) { var dict = (AttachedValueDictionary)dependencyObject.GetValue(AttachedValueDictionaryProperty); if (dict == null && addNew) { dict = new AttachedValueDictionary(); dependencyObject.SetValue(AttachedValueDictionaryProperty, dict); } return(dict); } #elif XAMARIN_FORMS var bindableObject = item as BindableObject; if (bindableObject != null) { var dict = (AttachedValueDictionary)bindableObject.GetValue(AttachedValueDictionaryProperty); if (dict == null && addNew) { lock (_internalDictionary) { dict = (AttachedValueDictionary)bindableObject.GetValue(AttachedValueDictionaryProperty); if (dict == null) { dict = new AttachedValueDictionary(); bindableObject.SetValue(AttachedValueDictionaryProperty, dict); } } } return(dict); } #elif ANDROID if (SetTagSupported) { var view = item as View; if (view.IsAlive()) { var dict = (AttachedValueDictionaryJava)view.GetTag(Resource.Id.AttachedProperties); if (dict == null && addNew) { lock (_internalDictionary) { dict = (AttachedValueDictionaryJava)view.GetTag(Resource.Id.AttachedProperties); if (dict == null) { dict = new AttachedValueDictionaryJava(); view.SetTag(Resource.Id.AttachedProperties, dict); } } } return(dict?.Dictionary); } } #endif if (addNew) { return(_internalDictionary.GetValue(item, CreateDictionaryDelegate)); } AttachedValueDictionary value; _internalDictionary.TryGetValue(item, out value); return(value); }