开发者

WPF Visibility.Visible doesnt work when executing an external app from a WPF button;

开发者 https://www.devze.com 2023-03-20 04:39 出处:网络
I have the following code to launch an external application. When I click the button, i need to make it so that the page is greyed out so I make a rectangle already on the page visible and full screen

I have the following code to launch an external application. When I click the button, i need to make it so that the page is greyed out so I make a rectangle already on the page visible and full screen.

    private void uxOfficeApps_Click(object sender, RoutedEventArgs e)
    {
        Rectangle rect = FindChild<Rectangle>(ParentWindow, "rectangle1");
        rect.Height = _basePage.SCREEN_RESOLUTION_HEIGHT;
        rect.Width = _basePage.SCREEN_RESOLUTION_WIDTH;
        rect.Visibility = Visibility.Visible;

        string executablePath = _basePage.PATH_OFFICE;
        executable = new Process();
        executable.StartInfo.FileName = executablePath;
        executable.Start();
        executable.EnableRaisingEvents = true;
        executable.Exited += new EventHandler(officeApps_Exited);
        executable.WaitForExit();
   }

It works fine and the application waits and returns when my external application is closed, howver the rectangle is only displayed when the exitied event "officeApp_Exited" is executed, not before it was loaded as I would like. (the screen does not get updated)

the exit event is

void officeApps_Exited(object sender, EventArgs e)
{
        MessageBox.Show("I am back");
        // do further processing
}

the Visibility does not work.

However it does work when I put a MessageBox.Show("Alert") between making the rectangle visible and creating开发者_StackOverflow社区 the process object.

Does anyone know why ??? Please Help


Try wrapping your code in the Dispatcher.BeginInvoke. That should give the UI enough time to redraw before you start your process

    Dispatcher.BeginInvoke(new Action(() =>
    {
        string executablePath = _basePage.PATH_OFFICE;
        executable = new Process();
        executable.StartInfo.FileName = executablePath;
        executable.Start();
        executable.EnableRaisingEvents = true;
        executable.Exited += new EventHandler(officeApps_Exited);
        executable.WaitForExit();
    }), DispatcherPriority.ApplicationIdle);


Since you are asking application to WaitForExit() ui thread hangs for that operation.... so rectangle visibility will not show any effect till the process got exited...

Use the following code...

 new TaskFactory().StartNew(() =>
            {
 string executablePath = _basePage.PATH_OFFICE;
        executable = new Process();
        executable.StartInfo.FileName = executablePath;
        executable.Start();
        executable.EnableRaisingEvents = true;
        executable.Exited += new EventHandler(officeApps_Exited);
        executable.WaitForExit();
  });

in the above code i am running the process in a new task (just like background).... so UI thread will not hangs for the process exit....

void officeApps_Exited(object sender, EventArgs e)
{
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
                 {
        MessageBox.Show("I am back");
        // do further processing
 });
}

What ever you are doing in the "officeApps_Exited" move that to // do further processing.


I suspect your problem is that calling WaitForExit() is blocking the UI thread and so it is preventing the visibility change from being rendered. I'm not sure why putting up a MessageBox helps, maybe something to do with modal rendering causes it to re-paint the window before putting up the dialog. Try running the process start code in a BackgroundWorker and then performing the code in your Exited event handler using Dispatcher.Invoke() back to the UI thread.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号