public static void Start(this PropertyChangedEventHandler?Handler, object Sender, params string[] PropertyName)
        {
            if (PropertyName is null)
            {
                throw new ArgumentNullException(nameof(PropertyName));
            }
            if (Handler is null || PropertyName.Length == 0)
            {
                return;
            }
            var args = PropertyName.ToArray(name => new PropertyChangedEventArgs(name));

            foreach (var d in Handler.GetInvocationList())
            {
                switch (d.Target)
                {
                case ISynchronizeInvoke {
                        InvokeRequired: true
                } synchronize_invoke:
                    foreach (var arg in args)
                    {
                        synchronize_invoke.Invoke(d, new[] { Sender, arg });
                    }
                    break;

                default:
                    foreach (var arg in args)
                    {
                        d.DynamicInvoke(Sender, arg);
                    }
                    break;
                }
            }
        }
        public static bool MutateVerbose <TProperty>(this INotifyPropertyChanged self,
                                                     ref TProperty property,
                                                     TProperty value,
                                                     PropertyChangedEventHandler?eventHandler,
                                                     Dispatcher?dispatcher = null,
                                                     [CallerMemberName] string?propertyName = null)
        {
            if (EqualityComparer <TProperty> .Default.Equals(property, value))
            {
                return(false);
            }

            property = value;
            if (eventHandler == null)
            {
                return(true);
            }

            if (dispatcher == null || dispatcher.CheckAccess())
            {
                eventHandler.Invoke(self, new PropertyChangedEventArgs(propertyName));
            }
            else
            {
                dispatcher.Invoke(() => eventHandler.Invoke(self, new PropertyChangedEventArgs(propertyName)));
            }

            return(true);
        }
 /// <summary>
 /// Adds a handler, returning whether or not this has caused the underlying handler
 /// to go from "subscribed" to "unsubscribed".
 /// </summary>
 /// <param name="value">The handler to add.</param>
 /// <returns>true if there were previously no handlers, but now there's at least one; false otherwise.</returns>
 public static bool RemoveHandler(ref PropertyChangedEventHandler?field, PropertyChangedEventHandler?value)
 {
     if (value is null || field is null)
     {
         return(false);
     }
     field -= value;
     return(field is null);
 }
        /// <summary>
        /// Raises the <see cref="PropertyChanged"/> event.
        /// </summary>
        /// <param name="propertyName">The name of the property that has changed.</param>
        /// <remarks>
        /// This method is useful when setting one property via <see cref="Update"/>
        /// also causes a dependent "read-only" property to be updated.
        /// </remarks>
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler?handler = this.PropertyChanged;

            if (handler != null)
            {
                PropertyChangedEventArgs args = new(propertyName);
                handler(this, args);
            }
        }
        /// <summary>
        /// Adds a handler, returning whether or not this has caused the underlying handler
        /// to go from "unsubscribed" to "subscribed".
        /// </summary>
        /// <param name="value">The handler to add.</param>
        /// <returns>true if there were previously no handlers, but now there's at least one; false otherwise.</returns>
        public static bool AddHandler(ref PropertyChangedEventHandler?field, PropertyChangedEventHandler?value)
        {
            if (value is null)
            {
                return(false);
            }
            // TODO: Make this thread-safe.
            bool ret = field is null;

            field += value;
            return(ret);
        }
        /// <summary>
        ///     Raises the specified e.
        /// </summary>
        /// <param name="eventHandler">The event handler.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>
        ///     Is any raised.
        /// </returns>
        public static bool Raise(
            this PropertyChangedEventHandler?eventHandler,
            [CallerMemberName] string?propertyName = null !)
        {
            if (eventHandler == null)
            {
                return(false);
            }

            eventHandler(null, new PropertyChangedEventArgs(propertyName));
            return(true);
        }
Example #7
0
 // https://stackoverflow.com/a/60668668/111794
 public static void NotifyChanged <T>(
     this INotifyPropertyChanged inpc,
     ref T current, T newValue,
     PropertyChangedEventHandler?handler,
     [CallerMemberName] string?name = null)
 {
     if (EqualityComparer <T> .Default.Equals(current, newValue))
     {
         return;
     }
     current = newValue;
     handler?.Invoke(inpc, new PropertyChangedEventArgs(name));
 }
Example #8
0
        protected void WireUpForceUpdateSizeRequested(ICellController cell, UITableViewCell platformCell, UITableView tableView)
        {
            var inpc = cell as INotifyPropertyChanged;

            cell.ForceUpdateSizeRequested -= _onForceUpdateSizeRequested;

            if (inpc != null)
            {
                inpc.PropertyChanged -= _onPropertyChangedEventHandler;
            }

            _onForceUpdateSizeRequested = (sender, e) =>
            {
                var index = tableView?.IndexPathForCell(platformCell);
                if (index == null && sender is Cell c)
                {
                    index = Controls.Compatibility.Platform.iOS.CellExtensions.GetIndexPath(c);
                }

                if (index != null)
                {
                    tableView?.ReloadRows(new[] { index }, UITableViewRowAnimation.None);
                }
            };

            _onPropertyChangedEventHandler = (sender, e) =>
            {
                if (e.PropertyName == "RealCell" && sender is BindableObject bo && GetRealCell(bo) == null)
                {
                    if (sender is ICellController icc)
                    {
                        icc.ForceUpdateSizeRequested -= _onForceUpdateSizeRequested;
                    }

                    if (sender is INotifyPropertyChanged notifyPropertyChanged)
                    {
                        notifyPropertyChanged.PropertyChanged -= _onPropertyChangedEventHandler;
                    }

                    _onForceUpdateSizeRequested    = null;
                    _onPropertyChangedEventHandler = null;
                }
            };

            cell.ForceUpdateSizeRequested += _onForceUpdateSizeRequested;
            if (inpc != null)
            {
                inpc.PropertyChanged += _onPropertyChangedEventHandler;
            }
        }
        public static bool MutateVerboseIfNotNull <TProperty>(this INotifyPropertyChanged self,
                                                              ref TProperty property,
                                                              TProperty value,
                                                              PropertyChangedEventHandler?eventHandler,
                                                              Dispatcher?dispatcher = null,
                                                              [CallerMemberName] string?propertyName = null)
        {
            if (value == null)
            {
                return(false);
            }

            return(self.MutateVerbose(ref property, value, eventHandler, dispatcher, propertyName));
        }
Example #10
0
        public static bool RaiseAndSetIfChanged <T, U>(
            this T @this,
            ref U backingField,
            U newValue,
            PropertyChangedEventHandler?propertyChangedEventHandler,
            [CallerMemberName] string propertyName = ""
            ) where T : INotifyPropertyChanged
        {
            var changed = !EqualityComparer <U> .Default.Equals(backingField, newValue);

            if (changed)
            {
                backingField = newValue;
                propertyChangedEventHandler?.Invoke(@this, new PropertyChangedEventArgs(propertyName));
            }
            return(changed);
        }
Example #11
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual void Intercept(IInvocation invocation)
        {
            var methodName = invocation.Method.Name;

            if (invocation.Method.DeclaringType == _notifyChangedInterface)
            {
                if (methodName == $"add_{nameof(INotifyPropertyChanged.PropertyChanged)}")
                {
                    _handler = (PropertyChangedEventHandler)Delegate.Combine(
                        _handler, (Delegate)invocation.Arguments[0]);
                }
                else if (methodName == $"remove_{nameof(INotifyPropertyChanged.PropertyChanged)}")
                {
                    _handler = (PropertyChangedEventHandler?)Delegate.Remove(
                        _handler, (Delegate)invocation.Arguments[0]);
                }
            }
            else if (methodName.StartsWith("set_", StringComparison.Ordinal))
            {
                var propertyName = FindPropertyName(invocation);

                var property = EntityType.FindProperty(propertyName);
                if (property != null)
                {
                    HandleChanged(invocation, property, GetValueComparer(property));
                }
                else
                {
                    var navigation = EntityType.FindNavigation(propertyName)
                                     ?? (INavigationBase?)EntityType.FindSkipNavigation(propertyName);

                    if (navigation != null)
                    {
                        HandleChanged(invocation, navigation, LegacyReferenceEqualityComparer.Instance);
                    }
                    else
                    {
                        invocation.Proceed();
                    }
                }
            }
            else
            {
                invocation.Proceed();
            }
        }
Example #12
0
        public static void ThreadSafeInvoke(
            this PropertyChangedEventHandler?Event,
            object?sender,
            [NotNull, ItemCanBeNull] params string[] PropertyName)
        {
            if (PropertyName is null)
            {
                throw new ArgumentNullException(nameof(PropertyName));
            }
            if (Event is null || PropertyName.Length == 0)
            {
                return;
            }
            var args = PropertyName.ToArray(name => new PropertyChangedEventArgs(name));

            foreach (var d in Event.GetInvocationList())
            {
                switch (d.Target)
                {
                case ISynchronizeInvoke {
                        InvokeRequired: true
                } synchronize_invoke:
                    foreach (var arg in args)
                    {
                        synchronize_invoke.Invoke(d, new[] { sender, arg });
                    }
                    break;

                case DispatcherObject dispatcher_obj when !dispatcher_obj.CheckAccess():
                    foreach (var arg in args)
                    {
                        dispatcher_obj.Dispatcher.Invoke(d, arg);
                    }
                    break;

                default:
                    foreach (var arg in args)
                    {
                        d.DynamicInvoke(sender, arg);
                    }
                    break;
                }
            }
        }
Example #13
0
        public static void ThreadSafeBeginInvoke(
            this PropertyChangedEventHandler?Handler,
            object?Sender,
            [NotNull] string PropertyName)
        {
            if (PropertyName is null)
            {
                throw new ArgumentNullException(nameof(PropertyName));
            }
            if (Handler is null || PropertyName.Length == 0)
            {
                return;
            }
            var e = new PropertyChangedEventArgs(PropertyName);
            var invocation_list = Handler.GetInvocationList();
            var args            = new[] { Sender, e };

            foreach (var d in invocation_list)
            {
                switch (d.Target)
                {
                case ISynchronizeInvoke {
                        InvokeRequired: true
                } synchronize_invoke:
                    synchronize_invoke.BeginInvoke(d, args);
                    break;

                case DispatcherObject {
                        Dispatcher: { }
                } dispatcher_obj when !dispatcher_obj.CheckAccess() :
                    dispatcher_obj.Dispatcher.BeginInvoke(d, DispatcherPriority.DataBind, args);
                    break;

                default:
                {
                    var @delegate = d;
                    ((Action <object[]>)(a => @delegate.DynamicInvoke(a))).BeginInvoke(args !, null, null);
                    break;
                }
                }
            }
        }
Example #14
0
        public MethodToCommandConverter(Delegate action)
        {
            var target = action.Target;
            var canExecuteMethodName = "Can" + action.Method.Name;
            var parameters           = action.Method.GetParameters();
            var parameterInfo        = parameters.Length == 0 ? null : parameters[0].ParameterType;

            if (parameterInfo == null)
            {
                execute = CreateExecute(target, action.Method);
            }
            else
            {
                execute = CreateExecute(target, action.Method, parameterInfo);
            }

            var canExecuteMethod = action.Method.DeclaringType?.GetRuntimeMethods()
                                   .FirstOrDefault(m => m.Name == canExecuteMethodName &&
                                                   m.GetParameters().Length == 1 &&
                                                   m.GetParameters()[0].ParameterType == typeof(object));

            if (canExecuteMethod == null)
            {
                canExecute = AlwaysEnabled;
            }
            else
            {
                canExecute           = CreateCanExecute(target, canExecuteMethod);
                dependencyProperties = canExecuteMethod
                                       .GetCustomAttributes(typeof(Metadata.DependsOnAttribute), true)
                                       .OfType <Metadata.DependsOnAttribute>()
                                       .Select(x => x.Name)
                                       .ToArray();
                if (dependencyProperties.Any() &&
                    target is INotifyPropertyChanged inpc)
                {
                    propertyChangedEventHandler = OnPropertyChanged;
                    weakPropertyChanged         = new WeakPropertyChangedProxy(inpc, propertyChangedEventHandler);
                }
            }
        }
Example #15
0
        public static void Start(this PropertyChangedEventHandler?Handler, object Sender, PropertyChangedEventArgs e)
        {
            if (Handler is null)
            {
                return;
            }
            foreach (var d in Handler.GetInvocationList())
            {
                switch (d.Target)
                {
                case ISynchronizeInvoke {
                        InvokeRequired: true
                } synchronize_invoke:
                    synchronize_invoke.Invoke(d, new[] { Sender, e });
                    break;

                default:
                    d.DynamicInvoke(Sender, e);
                    break;
                }
            }
        }
Example #16
0
 public ISettingsBuilder SetOnPropertyChanged(PropertyChangedEventHandler value)
 {
     OnPropertyChanged = value; return(this);
 }
Example #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SubscriptionBase"/> class.
        /// </summary>
        /// <param name="application">The UaApplication.</param>
        /// <param name="runtimeSubscriptionAttribute">The optional attribute created at runtime.</param>
        public SubscriptionBase(UaApplication?application, SubscriptionAttribute?runtimeSubscriptionAttribute = null)
        {
            this.application = application ?? throw new ArgumentNullException(nameof(application));
            this.application.Completion.ContinueWith(t => this.stateMachineCts?.Cancel());
            this.logger           = this.application.LoggerFactory?.CreateLogger(this.GetType());
            this.errors           = new ErrorsContainer <string>(p => this.ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(p)));
            this.progress         = new Progress <CommunicationState>(s => this.State = s);
            this.propertyChanged += this.OnPropertyChanged;
            this.whenSubscribed   = new TaskCompletionSource <bool>();
            this.whenUnsubscribed = new TaskCompletionSource <bool>();
            this.whenUnsubscribed.TrySetResult(true);

            // register the action to be run on the ui thread, if there is one.
            if (SynchronizationContext.Current != null)
            {
                this.actionBlock = new ActionBlock <PublishResponse>(pr => this.OnPublishResponse(pr), new ExecutionDataflowBlockOptions {
                    SingleProducerConstrained = true, TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
                });
            }
            else
            {
                this.actionBlock = new ActionBlock <PublishResponse>(pr => this.OnPublishResponse(pr), new ExecutionDataflowBlockOptions {
                    SingleProducerConstrained = true
                });
            }

            var typeInfo = this.GetType().GetTypeInfo();

            // read [Subscription] attribute.
            var sa = runtimeSubscriptionAttribute ?? typeInfo.GetCustomAttribute <SubscriptionAttribute>();

            if (sa != null)
            {
                this.endpointUrl        = sa.EndpointUrl;
                this.publishingInterval = sa.PublishingInterval;
                this.keepAliveCount     = sa.KeepAliveCount;
                this.lifetimeCount      = sa.LifetimeCount;
            }

            // read [MonitoredItem] attributes.
            foreach (var propertyInfo in typeInfo.DeclaredProperties)
            {
                var mia = propertyInfo.GetCustomAttribute <MonitoredItemAttribute>();
                if (mia == null || string.IsNullOrEmpty(mia.NodeId))
                {
                    continue;
                }

                MonitoringFilter?filter = null;
                if (mia.AttributeId == AttributeIds.Value && (mia.DataChangeTrigger != DataChangeTrigger.StatusValue || mia.DeadbandType != DeadbandType.None))
                {
                    filter = new DataChangeFilter()
                    {
                        Trigger = mia.DataChangeTrigger, DeadbandType = (uint)mia.DeadbandType, DeadbandValue = mia.DeadbandValue
                    };
                }

                var propType = propertyInfo.PropertyType;
                if (propType == typeof(DataValue))
                {
                    this.monitoredItems.Add(new DataValueMonitoredItem(
                                                target: this,
                                                property: propertyInfo,
                                                nodeId: ExpandedNodeId.Parse(mia.NodeId),
                                                indexRange: mia.IndexRange,
                                                attributeId: mia.AttributeId,
                                                samplingInterval: mia.SamplingInterval,
                                                filter: filter,
                                                queueSize: mia.QueueSize,
                                                discardOldest: mia.DiscardOldest));
                    continue;
                }

                if (propType == typeof(BaseEvent) || propType.GetTypeInfo().IsSubclassOf(typeof(BaseEvent)))
                {
                    this.monitoredItems.Add(new EventMonitoredItem(
                                                target: this,
                                                property: propertyInfo,
                                                nodeId: ExpandedNodeId.Parse(mia.NodeId),
                                                indexRange: mia.IndexRange,
                                                attributeId: mia.AttributeId,
                                                samplingInterval: mia.SamplingInterval,
                                                filter: new EventFilter()
                    {
                        SelectClauses = EventHelper.GetSelectClauses(propType)
                    },
                                                queueSize: mia.QueueSize,
                                                discardOldest: mia.DiscardOldest));
                    continue;
                }

                if (propType == typeof(ObservableQueue <DataValue>))
                {
                    this.monitoredItems.Add(new DataValueQueueMonitoredItem(
                                                target: this,
                                                property: propertyInfo,
                                                nodeId: ExpandedNodeId.Parse(mia.NodeId),
                                                indexRange: mia.IndexRange,
                                                attributeId: mia.AttributeId,
                                                samplingInterval: mia.SamplingInterval,
                                                filter: filter,
                                                queueSize: mia.QueueSize,
                                                discardOldest: mia.DiscardOldest));
                    continue;
                }

                if (propType.IsConstructedGenericType && propType.GetGenericTypeDefinition() == typeof(ObservableQueue <>))
                {
                    var elemType = propType.GenericTypeArguments[0];
                    if (elemType == typeof(BaseEvent) || elemType.GetTypeInfo().IsSubclassOf(typeof(BaseEvent)))
                    {
                        this.monitoredItems.Add((MonitoredItemBase)Activator.CreateInstance(
                                                    typeof(EventQueueMonitoredItem <>).MakeGenericType(elemType),
                                                    this,
                                                    propertyInfo,
                                                    ExpandedNodeId.Parse(mia.NodeId),
                                                    mia.AttributeId,
                                                    mia.IndexRange,
                                                    MonitoringMode.Reporting,
                                                    mia.SamplingInterval,
                                                    new EventFilter()
                        {
                            SelectClauses = EventHelper.GetSelectClauses(elemType)
                        },
                                                    mia.QueueSize,
                                                    mia.DiscardOldest) !);
                        continue;
                    }
                }

                this.monitoredItems.Add(new ValueMonitoredItem(
                                            target: this,
                                            property: propertyInfo,
                                            nodeId: ExpandedNodeId.Parse(mia.NodeId),
                                            indexRange: mia.IndexRange,
                                            attributeId: mia.AttributeId,
                                            samplingInterval: mia.SamplingInterval,
                                            filter: filter,
                                            queueSize: mia.QueueSize,
                                            discardOldest: mia.DiscardOldest));
            }

            this.stateMachineCts  = new CancellationTokenSource();
            this.stateMachineTask = Task.Run(() => this.StateMachineAsync(this.stateMachineCts.Token));
        }
 private ExternalPerSaveSettings(string id, string displayName, string folderName, string subFolder, int uiVersion, char subGroupDelimiter, PropertyChangedEventHandler?onPropertyChanged, IEnumerable <SettingsPropertyGroupDefinition> settingPropertyGroups, Dictionary <string, ISettingsPresetBuilder> presets)
     : base(id, displayName, folderName, subFolder, uiVersion, subGroupDelimiter, onPropertyChanged, settingPropertyGroups, presets)
 {
 }
Example #19
0
        /// <summary>
        /// Sets the data for the specified class at the specified index.  If the class has
        /// changed then a full look for the slot will be performed.  If the new class does
        /// not have the provided slot then the Expando's class will change. Only case sensitive
        /// setter is supported in ExpandoObject.
        /// </summary>
        internal void TrySetValue(object?indexClass, int index, object?value, string name, bool ignoreCase, bool add)
        {
            ExpandoData data;
            object?     oldValue;

            lock (LockObject)
            {
                data = _data;

                if (data.Class != indexClass || ignoreCase)
                {
                    // The class has changed or we are doing a case-insensitive search,
                    // we need to get the correct index and set the value there.  If we
                    // don't have the value then we need to promote the class - that
                    // should only happen when we have multiple concurrent writers.
                    index = data.Class.GetValueIndex(name, ignoreCase, this);
                    if (index == ExpandoObject.AmbiguousMatchFound)
                    {
                        throw System.Linq.Expressions.Error.AmbiguousMatchInExpandoObject(name);
                    }
                    if (index == ExpandoObject.NoMatch)
                    {
                        // Before creating a new class with the new member, need to check
                        // if there is the exact same member but is deleted. We should reuse
                        // the class if there is such a member.
                        int exactMatch = ignoreCase ?
                                         data.Class.GetValueIndexCaseSensitive(name) :
                                         index;
                        if (exactMatch != ExpandoObject.NoMatch)
                        {
                            Debug.Assert(data[exactMatch] == Uninitialized);
                            index = exactMatch;
                        }
                        else
                        {
                            ExpandoClass newClass = data.Class.FindNewClass(name);
                            data = PromoteClassCore(data.Class, newClass);
                            // After the class promotion, there must be an exact match,
                            // so we can do case-sensitive search here.
                            index = data.Class.GetValueIndexCaseSensitive(name);
                            Debug.Assert(index != ExpandoObject.NoMatch);
                        }
                    }
                }

                // Setting an uninitialized member increases the count of available members
                oldValue = data[index];
                if (oldValue == Uninitialized)
                {
                    _count++;
                }
                else if (add)
                {
                    throw System.Linq.Expressions.Error.SameKeyExistsInExpando(name);
                }

                data[index] = value;
            }

            // Notify property changed outside the lock
            PropertyChangedEventHandler?propertyChanged = _propertyChanged;

            if (propertyChanged != null && value != oldValue)
            {
                propertyChanged(this, new PropertyChangedEventArgs(data.Class.Keys[index]));
            }
        }
 /// <summary>
 /// Notifies multiple property changed
 /// </summary>
 /// <param name="propertyChangedImplementation">The property changed implementation, this is normally a view model</param>
 /// <param name="propertyChanged">The property changed event handler that the propertyChangedImplementation holds</param>
 /// <param name="properties"></param>
 public static void OnMultiplePropertiesChanged(this INotifyPropertyChanged propertyChangedImplementation, PropertyChangedEventHandler?propertyChanged, params string[] properties)
 {
     propertyChanged?.RaiseForEach(propertyChangedImplementation, properties);
 }
        public static ExternalPerSaveSettings?CreateFromXmlStream(Stream xmlStream, Func <IPropertyDefinitionBase, IRef> assignRefDelegate, PropertyChangedEventHandler?propertyChanged = null)
        {
            using var reader = XmlReader.Create(xmlStream, new XmlReaderSettings { IgnoreComments = true, IgnoreWhitespace = true });
            var serializer = new XmlSerializer(typeof(SettingsXmlModel));

            if (!serializer.CanDeserialize(reader) || serializer.Deserialize(reader) is not SettingsXmlModel settingsXmlModel)
            {
                return(null);
            }

            var subGroupDelimiter = settingsXmlModel.SubGroupDelimiter[0];

            var props = settingsXmlModel.Groups
                        .SelectMany(g => g.Properties.Select(p =>
                                                             new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(p), g, assignRefDelegate(p), subGroupDelimiter)))
                        .Concat(settingsXmlModel.Properties.Select(p =>
                                                                   new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(p), SettingsPropertyGroupDefinition.DefaultGroup, assignRefDelegate(p), subGroupDelimiter)));
            var propGroups = SettingsUtils.GetSettingsPropertyGroups(subGroupDelimiter, props);

            return(new ExternalPerSaveSettings(
                       settingsXmlModel.Id,
                       settingsXmlModel.DisplayName,
                       settingsXmlModel.FolderName,
                       settingsXmlModel.SubFolder,
                       settingsXmlModel.UIVersion,
                       subGroupDelimiter,
                       propertyChanged,
                       propGroups,
                       new Dictionary <string, ISettingsPresetBuilder>()));
        }
 /// <summary>
 /// Notifies property changed.
 /// </summary>
 /// <param name="propertyChangedImplementation">The property changed implementation, this is normally a view model </param>
 /// <param name="propertyChanged">The property changed event handler that the propertyChangedImplementation holds</param>
 /// <param name="propertyName">A nullable property name, if left empty it will pick the caller member name</param>
 public static void OnPropertyChanged(this INotifyPropertyChanged propertyChangedImplementation, PropertyChangedEventHandler?propertyChanged, [CallerMemberName] string propertyName = "")
 {
     propertyChanged?.Raise(propertyName, propertyChangedImplementation);
 }
        /// <summary>
        /// Sets a value to a backing field if it passes a equality check and notifies property changed.
        /// </summary>
        /// <typeparam name="S">The type of the property</typeparam>
        /// <param name="propertyChangedImplementation">The property changed implementation, this is normally a view model</param>
        /// <param name="backingStore">The backing store that will hold the value of the property</param>
        /// <param name="value">The new value that should be set</param>
        /// <param name="propertyChanged">The property changed event handler that the propertyChangedImplementation holds</param>
        /// <param name="propertyName">A nullable property name, if left empty it will pick the caller member name</param>
        /// <remarks>This method does a equality check to see if the value has changed, if you need to notify property changed when the value has not changed, please use <see cref="OnPropertyChanged"/></remarks>
        /// <returns>A boolean value to indicate that the property changed has been invoked</returns>
        public static bool Set <S>(this INotifyPropertyChanged propertyChangedImplementation, ref S backingStore, S value, PropertyChangedEventHandler?propertyChanged, [CallerMemberName] string propertyName = "")
        {
#pragma warning disable CS8604 // Disabled to be able to test RaiseAfter by calling Set, PropertyChanged should never actually be null in a Xamarin.Forms app and we do a null propagation check in RaiseAfter, so its safe to ignore
            return(propertyChanged.RaiseWhenSet(ref backingStore, value, propertyChangedImplementation, propertyName));

#pragma warning restore CS8604
        }
Example #24
0
 public static bool RaiseSetAndObserveIfChanged <T, U, V>(
     this T @this,
     ref Arr <U> backingField,
     Arr <U> newValue,
     PropertyChangedEventHandler?propertyChangedEventHandler,
     ISubject <(Arr <U> Us, ObservableQualifier ObservableQualifier)> changesSubject,
Example #25
0
 public static void Raise(this PropertyChangedEventHandler?handler, object?sender, [CallerMemberName] string?memberName = null)
 {
     handler?.Invoke(sender, new PropertyChangedEventArgs(memberName));
 }
Example #26
0
 /*注释:如果将更改属性名设为String.Empty,
  * 可以通知索引器已经更改,
  * 但如果填入索引器的默认名称Item,则不会发出通知,
  * 原因可能是索引器能够重载*/
 #endregion
 #region  统事件版本
 /// <summary>
 /// 调用一个<see cref="INotifyPropertyChanged.PropertyChanged"/>事件,
 /// 自动填入调用属性的名称
 /// </summary>
 /// <param name="obj">要引发事件的<see cref="INotifyPropertyChanged"/>对象</param>
 /// <param name="delegate"><see cref="INotifyPropertyChanged.PropertyChanged"/>事件的传统委托封装</param>
 /// <param name="propertyName">调用属性的名称,可自动获取,如果是<see cref="string.Empty"/>,代表所有属性都已更改</param>
 public static void Changed(this INotifyPropertyChanged obj, PropertyChangedEventHandler? @delegate, [CallerMemberName] string propertyName = "")
 => @delegate?.Invoke(obj, new PropertyChangedEventArgs(propertyName));
 public static void Raise(this PropertyChangedEventHandler?handler, object sender, string propertyName)
 {
     handler?.Invoke(sender, new PropertyChangedEventArgs(propertyName));
 }
 protected BaseFluentGlobalSettingsWrapper(object @object, string id, string displayName, string folderName, string subFolder, string format,
                                           int uiVersion, char subGroupDelimiter, PropertyChangedEventHandler?onPropertyChanged,
                                           IEnumerable <SettingsPropertyGroupDefinition> settingPropertyGroups, Dictionary <string, ISettingsPresetBuilder> presets)
     : base(id, displayName, folderName, subFolder, format, uiVersion, subGroupDelimiter, onPropertyChanged, settingPropertyGroups, presets)
 {
     Object = @object;
 }