예제 #1
0
        static Dispatcher()
        {
            Type?implType = null;

            try
            {
                implType = AppDomain.CurrentDomain
                           .GetAssemblies()
                           .SelectMany(a => a.GetTypes())
                           .FirstOrDefault(type => !type.IsAbstract && typeof(Dispatcher).IsAssignableFrom(type) && type != typeof(Dispatcher));
            }
            catch (Exception ex)
            {
                Debug.Fail($"Failed to query all assembly types: {ex}");
            }

            if (implType == null)
            {
                Debug.Print($"No implementation of {nameof(Dispatcher)} has been found.");
                return;
            }

            try
            {
                Instance = (Dispatcher)Activator.CreateInstance(implType) !;
                return;
            }
            catch (Exception ex)
            {
                Debug.Fail($"Failed to create an intance of {implType.FullName}: {ex}");
            }
        }
        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);
        }
예제 #3
0
        /// <param name="interval">Timeout in Milliseconds</param>
        /// <param name="action">Action<object> to fire when debounced event fires</object></param>
        /// <param name="optParam">optional parameter</param>
        /// <param name="priority">optional priorty for the dispatcher</param>
        /// <param name="dispatcher">optional dispatcher. If not passed or null CurrentDispatcher is used.</param>
        public void Debounce(int interval,
                             Action <object?> action,
                             object?optParam             = null,
                             DispatcherPriority priority = DispatcherPriority.ApplicationIdle,
                             Dispatcher?dispatcher       = null)
        {
            // kill pending timer and pending ticks
            _timer?.Stop();
            _timer = null;

            dispatcher ??= Dispatcher.CurrentDispatcher;

            // timer is recreated for each event and effectively resets the timeout.
            // Action only fires after timeout has fully elapsed without other events firing in between
            _timer = new DispatcherTimer(TimeSpan.FromMilliseconds(interval),
                                         priority,
                                         (s, e) =>
            {
                if (_timer == null)
                {
                    return;
                }

                _timer?.Stop();
                _timer = null;
                action.Invoke(optParam);
            },
                                         dispatcher);

            _timer.Start();
        }
예제 #4
0
        private static T InternalInvoke <T>([CanBeNull] Dispatcher?dispatcher, [NotNull] Func <T> method)
        {
            var result = InternalInvoke(dispatcher, (Delegate)method);

            if (result == null)
            {
                return(default);
        public Action <Action <TWindow> > DisplayWindow <TWindow>(Func <TWindow> createWindow)
            where TWindow : class, IDisplayable
        {
            Dispatcher?threadDispatcher = null;
            TWindow?   window           = null;
            var        thread           = new Thread(
                () =>
            {
                threadDispatcher = Dispatcher.CurrentDispatcher;
                SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(threadDispatcher));

                window = createWindow();
                window.Restore();

                Dispatcher.Run();
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();

            void ExecuteWithDispatcher(Action <TWindow> action)
            {
                _ = window ?? throw new InvalidOperationException("Window is null");
                _ = threadDispatcher ?? throw new InvalidOperationException("ThreadDispatcher is null");

                threadDispatcher.BeginInvoke(() => { action(window); });
            }

            return(ExecuteWithDispatcher);
        }
예제 #6
0
        private static T?InternalInvoke <T>(Dispatcher?dispatcher, Func <T> method)
        {
            var result = InternalInvoke(dispatcher, (Delegate)method);

            if (result == null)
            {
                return(default);
예제 #7
0
 public void SetExportProvider(Dispatcher dispatcher, ExportProvider exportProvider)
 {
     this.dispatcher = dispatcher;
     if (!(this.exportProvider is null))
     {
         throw new InvalidOperationException();
     }
     this.exportProvider = exportProvider ?? throw new ArgumentNullException(nameof(exportProvider));
 }
예제 #8
0
        private void ThreadMethod()
        {
            // Start the dispatcher of the thread and set the started event
            _dispatcher = Dispatcher.CurrentDispatcher;
            _dispatcher.BeginInvoke(new ThreadStart(() => _threadStarted.Set()), DispatcherPriority.Send);

            Dispatcher.Run();

            Terminated?.Invoke(this, EventArgs.Empty);

            _threadStarted.Close();
        }
        /// <summary>
        /// Creates an instance of the <see cref="NotificationManager"/>
        /// </summary>
        /// <param name="mainNotificationPosition">The position where notifications with no custom area should
        /// be displayed</param>
        /// <param name="dispatcher">The <see cref="Dispatcher"/> that should be used</param>
        public NotificationManager(NotificationPosition mainNotificationPosition,
                                   Dispatcher?dispatcher)
        {
            _mainNotificationPosition = mainNotificationPosition;

            if (dispatcher == null)
            {
                dispatcher = Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher;
            }

            _dispatcher = dispatcher;
        }
        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));
        }
예제 #11
0
        /// <summary>
        /// Gets the <see cref="Window"/> associated with <paramref name="hwnd"/> which belongs to <paramref name="dispatcher"/>.
        /// </summary>
        /// <returns>
        /// <c>null</c> if <paramref name="hwnd"/> or <paramref name="dispatcher"/> are <c>null</c>.
        /// </returns>
        public static Window?GetVisibleWindow(IntPtr hwnd, Dispatcher?dispatcher)
        {
            if (hwnd == IntPtr.Zero ||
                dispatcher is null)
            {
                return(null);
            }

            var hwndSource = HwndSource.FromHwnd(hwnd);

            if (hwndSource is not null &&
                (hwndSource.Dispatcher is null || hwndSource.CheckAccess()) &&
                hwndSource.RootVisual is Window window &&
                window.Dispatcher == dispatcher &&
                window.Visibility == Visibility.Visible)
            {
                return(window);
            }

            return(null);
        }
예제 #12
0
        /// <param name="interval">Timeout in Milliseconds</param>
        /// <param name="action">Action<object> to fire when debounced event fires</object></param>
        /// <param name="optParam">optional parameter</param>
        /// <param name="priority">optional priorty for the dispatcher</param>
        /// <param name="dispatcher">optional dispatcher. If not passed or null CurrentDispatcher is used.</param>
        public void Throttle(int interval,
                             Action <object?> action,
                             object?optParam             = null,
                             DispatcherPriority priority = DispatcherPriority.ApplicationIdle,
                             Dispatcher?dispatcher       = null)
        {
            // kill pending timer and pending ticks
            _timer?.Stop();
            _timer = null;

            dispatcher ??= Dispatcher.CurrentDispatcher;

            var curTime = DateTime.UtcNow;

            // if timeout is not up yet - adjust timeout to fire
            // with potentially new Action parameters
            if (curTime.Subtract(_timerStarted).TotalMilliseconds < interval)
            {
                interval -= (int)curTime.Subtract(_timerStarted).TotalMilliseconds;
            }

            _timer = new DispatcherTimer(TimeSpan.FromMilliseconds(interval),
                                         priority,
                                         (s, e) =>
            {
                if (_timer == null)
                {
                    return;
                }

                _timer?.Stop();
                _timer = null;
                action.Invoke(optParam);
            },
                                         dispatcher);

            _timer.Start();
            _timerStarted = curTime;
        }
예제 #13
0
 protected ViewModel(Dispatcher?eventDispatcher) : base(eventDispatcher)
 {
 }
예제 #14
0
 /// <summary>
 /// Called after the behavior is attached to an <see cref="Behavior{UIElement}.AssociatedObject"/>
 /// </summary>
 protected override void OnAttached()
 {
     base.OnAttached();
     dispatcher = AssociatedObject.Dispatcher;
     ThreadPool.QueueUserWorkItem(DelayCallback);
 }
예제 #15
0
 /// <summary>
 /// Invokes the specified method in the dispatcher thread.
 /// </summary>
 /// <param name="dispatcher">The dispatcher.</param>
 /// <param name="method">The method.</param>
 /// <remarks>Exceptions thrown by <paramref name="method"/> are passed back to the caller and are not wrapped into a <see cref="TargetInvocationException"/>.</remarks>
 public static void Invoke([CanBeNull] this Dispatcher?dispatcher, [NotNull] Action method)
 {
     InternalInvoke(dispatcher, method);
 }
예제 #16
0
 public static T Invoke <T>([CanBeNull] this Dispatcher?dispatcher, [NotNull] Func <T> method)
 {
     return(InternalInvoke(dispatcher, method));
 }
예제 #17
0
 public void PlatformInitialize(Dispatcher uiThreadDispatcher, ContentControl root)
 {
     _uiThreadDispatcher = uiThreadDispatcher;
     _root = root;
 }
예제 #18
0
 public void PlatformInitialize(Dispatcher uiThreadDispatcher, IMvxWpfViewPresenter presenter)
 {
     _uiThreadDispatcher = uiThreadDispatcher;
     _presenter          = presenter;
 }
 protected NotifyPropertyChanged(Dispatcher?eventDispatcher = null)
 {
     EventDispatcher = eventDispatcher;
 }
 /// <summary>
 /// Creates an instance of the <see cref="NotificationManager"/>
 /// </summary>
 /// <param name="dispatcher">The <see cref="Dispatcher"/> that should be used</param>
 public NotificationManager(Dispatcher?dispatcher) : this(NotificationPosition.BottomRight, dispatcher)
 {
 }
예제 #21
0
 /// <summary>
 /// Gets the <see cref="Window"/> associated with <paramref name="hwnd"/> which belongs to <paramref name="dispatcher"/>.
 /// </summary>
 /// <returns>
 /// <c>null</c> if <paramref name="hwnd"/> or <paramref name="dispatcher"/> are <c>null</c>.
 /// </returns>
 public static Window?GetVisibleWindow(long hwnd, Dispatcher?dispatcher)
 {
     return(GetVisibleWindow(new IntPtr(hwnd), dispatcher));
 }
예제 #22
0
 /// <summary>
 /// Invokes the specified method in the dispatcher thread.
 /// </summary>
 /// <typeparam name="T">The return type of the method.</typeparam>
 /// <param name="dispatcher">The dispatcher.</param>
 /// <param name="method">The method.</param>
 /// <returns>The result of the method.</returns>
 /// <remarks>Exceptions thrown by <paramref name="method"/> are passed back to the caller and are not wrapped into a <see cref="TargetInvocationException"/>.</remarks>
 public static T?Invoke <T>(this Dispatcher?dispatcher, Func <T> method)
 {
     return(InternalInvoke(dispatcher, method));
 }
예제 #23
0
 /// <summary>
 /// Invokes the specified method in the dispatcher thread.
 /// </summary>
 /// <param name="dispatcher">The dispatcher.</param>
 /// <param name="method">The method.</param>
 /// <remarks>Exceptions thrown by <paramref name="method"/> are passed back to the caller and are not wrapped into a <see cref="TargetInvocationException"/>.</remarks>
 public static void Invoke(this Dispatcher?dispatcher, Action method)
 {
     InternalInvoke(dispatcher, method);
 }