/// <summary>
        /// This will add the action to a list of actions to perform at once in a Dispatcher.Invoke call.
        /// This has better performance than calling Dispatcher.BeginInvoke directly, because all the
        /// queued actions are performed together in a single Dispatch.BeginInvoke call.
        /// </summary>
        /// <param name="action">The action to queue.</param>
        public static void QueueAction(Action action)
        {
            _pendingActionsExecute.Add(action);

            if (!_isDispatcherPending)
            {
                _isDispatcherPending = true;

                if (_dispatcher == null)
                {
#if MIGRATION
                    _dispatcher = Dispatcher.INTERNAL_GetCurrentDispatcher();
#else
                    _dispatcher = CoreDispatcher.INTERNAL_GetCurrentDispatcher();
#endif
                }

                _dispatcher.BeginInvoke((Action)(() =>
                {
                    if (_isDispatcherPending)     // We check again in case it has been cancelled - not sure if useful though
                    {
                        ExecutePendingActions();
                    }
                }));
            }
        }
Beispiel #2
0
        public void BeginUpdateLayout()
        {
            if (updateLayoutOperation == null || updateLayoutOperation.Status == DispatcherOperationStatus.Completed)
            {
#if MIGRATION
                updateLayoutOperation = Dispatcher.INTERNAL_GetCurrentDispatcher().InvokeAsync(UpdateLayout, DispatcherPriority.Render);
#else
                updateLayoutOperation = CoreDispatcher.INTERNAL_GetCurrentDispatcher().InvokeAsync(UpdateLayout, DispatcherPriority.Render);
#endif
            }
        }
Beispiel #3
0
        /// <summary>
        /// Print a specific element.
        /// </summary>
        /// <param name="element">The element to print.</param>
        public static void Print(FrameworkElement element)
        {
            if (!Interop.IsRunningInTheSimulator)
            {
                // Remember the previous print area, if any:
                var previousPrintArea = CurrentPrintArea;

                // Check whether the element is aready in the Visual Tree:
                if (element._isLoaded)
                {
                    //---------------------------------------------------
                    // The element is already in the Visual Tree.
                    // (in this case, the "Print" method is synchronous)
                    //---------------------------------------------------

                    // Temporarily set the print area to the element that the user wants to print:
                    SetPrintArea(element);

                    // Print:
                    Print();

                    // Revert to the previous print area:
                    RestorePreviousPrintArea(previousPrintArea);
                }
                else
                {
                    //---------------------------------------------------
                    // The element is not in the Visual Tree.
                    // (in this case, the "Print" method is asynchronous)
                    //---------------------------------------------------

                    // Create and show a popup that will be used to temporarily put the element into the visual tree. This is required in order to be able to print it. We show the popup off-screen so that it is not visible:
                    var temporaryPopup = new Popup()
                    {
                        VerticalOffset = 10000
                    };
                    temporaryPopup.IsOpen = true;

                    // Create a container for the element
                    var container = new Border()
                    {
                        Child = element
                    };

                    // Listen to the "Loaded" event of the container, so that we are notified when the element becomes visible:
                    container.Loaded += (s2, e2) =>
                    {
                        // Print the element:
                        PrintManager.Print(element);

                        // Revert to the previous print area:
                        RestorePreviousPrintArea(previousPrintArea);

                        // Close the temporary popup:
                        CoreDispatcher.INTERNAL_GetCurrentDispatcher().BeginInvoke(() =>
                        {
                            temporaryPopup.IsOpen = false;
                        });
                    };

                    // Put the container into the popup, and open the popup:
                    temporaryPopup.Child  = container;
                    temporaryPopup.IsOpen = true;
                }
            }
            else
            {
                MessageBox.Show("The application requested to print. This feature is not implemented in the Simulator. Please run the application in the browser instead.");
            }
        }
Beispiel #4
0
        public Application()
        {
            // Keep a reference to the startup assembly:
            StartupAssemblyInfo.StartupAssembly = this.GetType().Assembly;

            // Remember whether we are in "SL Migration" mode or not:
#if MIGRATION
            Interop.ExecuteJavaScript(@"document.isSLMigration = true");
#else
            Interop.ExecuteJavaScript(@"document.isSLMigration = false");
#endif

            //Interop.ExecuteJavaScript("document.raiseunhandledException = $0", (Action<object>)RaiseUnhandledException);


            // Inject the "DataContractSerializer" into the "XmlSerializer" (read note in the "XmlSerializer" implementation to understand why):
            if (!Interop.IsRunningInTheSimulator) //Note: in case of the Simulator, we reference the .NET Framework version of "System.xml.dll", so we cannot inject stuff because the required members of XmlSerializer would be missing.
            {
                InjectDataContractSerializerIntoXmlSerializer();
            }

#if !CSHTML5NETSTANDARD
            // Fix the freezing of the Simulator when calling 'alert' using the "Interop.ExecuteJavaScript()" method by redirecting the JavaScript "alert" to the Simulator message box:
            if (Interop.IsRunningInTheSimulator)
            {
                RedirectAlertToMessageBox_SimulatorOnly();
            }
#endif

            // Keep a reference to the app:
            Application.Current = this;

            // Initialize the window:
            if (_mainWindow == null) // Note: it could be != null if the user clicks "Restart" from the Simulator advanced options.
            {
                _mainWindow    = new Window();
                Window.Current = _mainWindow;
                object applicationRootDomElement = INTERNAL_HtmlDomManager.GetApplicationRootDomElement();
                _mainWindow.AttachToDomElement(applicationRootDomElement);

                // Listen to clicks anywhere in the window (this is used to close the popups that are not supposed to stay open):
#if MIGRATION
                _mainWindow.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(INTERNAL_PopupsManager.OnClickOnPopupOrWindow), true);
#else
                _mainWindow.AddHandler(UIElement.PointerPressedEvent, new PointerEventHandler(INTERNAL_PopupsManager.OnClickOnPopupOrWindow), true);
#endif

#if !CSHTML5NETSTANDARD
                // Workaround an issue on Firefox where the UI disappears if the window is resized and on some other occasions:
                if (INTERNAL_HtmlDomManager.IsFirefox())
                {
                    _mainWindow.SizeChanged += MainWindow_SizeChanged;
                    _timerForWorkaroundFireFoxIssue.Interval = new TimeSpan(0, 0, 2);
                    _timerForWorkaroundFireFoxIssue.Tick    += TimerForWorkaroundFireFoxIssue_Tick;
                }
#endif
            }

            // We call the "Startup" event and the "OnLaunched" method using the Dispatcher, because usually the user registers the "Startup" event in the constructor of the "App.cs" class, which is derived from "Application.cs", and therefore when we arrive here the event is not yet registered. Executing the code in the Dispatcher ensures that the constructor of the "App.cs" class has finished before running the code.
            CoreDispatcher.INTERNAL_GetCurrentDispatcher().BeginInvoke((Action)(() =>
            {
                // Raise the "Startup" event:
                if (this.Startup != null)
                {
                    Startup(this, new StartupEventArgs());
                }

                // Call the "OnLaunched" method:
                this.OnLaunched(new LaunchActivatedEventArgs());
            }));
        }