Philippe
Philippe

Reputation: 986

ChildWindow won't display when call from the main(Silverlight, C#)

I have a Silverlight application (edit: an Out-of-browser application with elevated trust) which must open a ChildWindow (for login purpose). When I (try to) call the event from the main (or any function called in the main), with the code below, nothing happens.

var credentials = new Credentials();
credentials.Closed += new EventHandler(Credentials_Closed);
credentials.Show();

I tried with a small test application and it was not working either. But then I tried to call the event from a Button_Click event... surprise, it works ! It also works when called by a DispatcherTimer.

I thought maybe it will works if I start it in another thread but it didn't solve the issue...

Your help will be very appreciated !

Philippe

Source : Why Won't the Silverlight ChildWindow Display?

For the test program : www.philippebellefeuille.com/StackOverflow/8074918/BugChildWindowInMain.rar

Upvotes: 3

Views: 1489

Answers (1)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93551

Just tried your sample and it was both a UI threading issue and "something else" :)

The timer version works fine as-is (because the ShowDialog is deferred).

The newthread version fails because of threading. Got it working using my old favorite helper method (OnUiThread). Again it only worked because the ShowDialog is deferred:

protected delegate void OnUiThreadDelegate();

protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate)
{
    if (Deployment.Current.Dispatcher.CheckAccess())
    {
        onUiThreadDelegate();
    }
    else
    {
        Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate);
    }
}

with a call like this:

private void showdialog()
{
    this.OnUiThread(() =>
    {
        var credentials = new Credentials();
        credentials.Closed += new EventHandler(Credentials_Closed);
        credentials.Show();
    });
}

The direct call is interesting as it just fails, even if you use the showDialog above.

The cause is as follows...

App.xaml.cs does this:

this.RootVisual = new MainPage();

That means that the MainPage is not part of the visual tree until after the constructor returns! If the parent of a ChildWindow is not in the visual tree then a ChildWindow will not show.

Solution - wait until the page is loaded!

e.g.

public MainPage()
{
    InitializeComponent();
    this.Loaded += MainPage_Loaded;
}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    showdialog();
}

Upvotes: 4

Related Questions