web-dev-qa-db-fra.com

Quelle est la différence entre les événements Window.Loaded et Window.ContentRendered

Quelle est la différence entre le Window.Loaded et Window.ContentRendered événements dans WPF? Est-ce que l'événement ContentRendered est appelé en premier?

La description de la Window.ContentRendered événement ici dit simplement

Se produit après le rendu du contenu d'une fenêtre.

La description de la Window.Loaded événement ici dit

Se produit lorsque l'élément est mis en forme, rendu et prêt pour l'interaction.

J'ai un cas où je veux définir le MaxHeight de la fenêtre à la hauteur de la zone de travail de l'écran qui affiche ma fenêtre. Dans quel événement dois-je le faire?

Modifier:

Je pense avoir trouvé ce que je cherchais, mais je suis encore plus confus maintenant. L'événement Loaded se produit d'abord, puis l'événement ContentRendered. Dans le livre Programming WPF de Chris Sells & Ian Griffiths, il est indiqué que l'événement Loaded est

Relevé juste avant que la fenêtre ne soit affichée

Alors que l'événement 'ContentRendered` est

Relevé lorsque le contenu de la fenêtre est rendu visuellement.

Cela contredit ce que dit la documentation MSDN à propos de l'événement Loaded:

Se produit lorsque l'élément est mis en forme, rendu et prêt pour l'interaction.

C'est encore plus déroutant maintenant.

51
Tony Vitabile

Je pense qu'il y a peu de différence entre les deux événements. Pour comprendre cela, j'ai créé un exemple simple de manipulation:

XAML

<Window x:Class="LoadedAndContentRendered.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        Name="MyWindow"
        Title="MainWindow" Height="1000" Width="525"
        WindowStartupLocation="CenterScreen"
        ContentRendered="Window_ContentRendered"     
        Loaded="Window_Loaded">

    <Grid Name="RootGrid">        
    </Grid>
</Window>

Code behind

private void Window_ContentRendered(object sender, EventArgs e)
{
    MessageBox.Show("ContentRendered");
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Loaded");
}   

Dans ce cas, le message Loaded apparaît en premier après le message ContentRendered. Cela confirme les informations contenues dans la documentation.

En général, dans WPF, l'événement Loaded est déclenché si l'élément:

est aménagé, rendu et prêt pour l'interaction.

Comme dans WPF, Window est le même élément, mais il doit s'agir généralement d'un contenu organisé dans un panneau racine (par exemple: Grid). Par conséquent, surveiller le contenu de Window et créer un événement ContentRendered. Remarques de MSDN:

Si la fenêtre n'a pas de contenu, cet événement n'est pas déclenché.

Autrement dit, si nous créons un Window:

<Window x:Class="LoadedAndContentRendered.MainWindow"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    Name="MyWindow"        
    ContentRendered="Window_ContentRendered" 
    Loaded="Window_Loaded" />

Cela ne fonctionnera que Loaded événement.

En ce qui concerne l'accès aux éléments du Window, ils fonctionnent de la même manière. Créons un Label dans le principal Grid de Window. Dans les deux cas, nous avons reçu avec succès l'accès à Width:

private void Window_ContentRendered(object sender, EventArgs e)
{
    MessageBox.Show("ContentRendered: " + SampleLabel.Width.ToString());
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Loaded: " + SampleLabel.Width.ToString());
}   

En ce qui concerne Styles et Templates, ils sont appliqués à ce stade avec succès et nous pourrons y accéder.

Par exemple, nous voulons ajouter un Button:

private void Window_ContentRendered(object sender, EventArgs e)
{
    MessageBox.Show("ContentRendered: " + SampleLabel.Width.ToString());

    Button b1 = new Button();
    b1.Content = "ContentRendered Button";
    RootGrid.Children.Add(b1);
    b1.Height = 25;
    b1.Width = 200;
    b1.HorizontalAlignment = HorizontalAlignment.Right;
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Loaded: " + SampleLabel.Width.ToString());

    Button b1 = new Button();
    b1.Content = "Loaded Button";
    RootGrid.Children.Add(b1);
    b1.Height = 25;
    b1.Width = 200;
    b1.HorizontalAlignment = HorizontalAlignment.Left;
}

Dans le cas de Loaded événement, Button à ajouter à Grid immédiatement à l'apparition du Window. Dans le cas de ContentRendered event, Button à ajouter à Grid après que tout son contenu apparaîtra.

Par conséquent, si vous souhaitez ajouter des éléments ou des modifications avant le chargement Window, vous devez utiliser l'événement Loaded. Si vous souhaitez effectuer les opérations associées au contenu de Window telles que la prise de captures d'écran, vous devrez utiliser un événement ContentRendered.

52
Anatoliy Nikolaev

Si vous visitez ce lien https://msdn.Microsoft.com/library/ms748948%28v=vs.100%29.aspx#Window_Lifetime_Events et faites défiler jusqu'à Événements de la durée de vie d'une fenêtre, ils vous montreront l'événement. ordre.

Ouvrir:

  1. SourceInitiated
  2. Activé
  3. Chargé
  4. ContentRendered

Proche:

  1. Fermeture
  2. Désactivé
  3. Fermé
42
sa_ddam213

Si vous utilisez la liaison de données, vous devez utiliser l'événement ContentRendered.

Pour le code ci-dessous, l'en-tête est NULL lorsque l'événement Loaded est déclenché. Cependant, Header obtient sa valeur lorsque l'événement ContentRendered est déclenché.

<MenuItem Header="{Binding NewGame_Name}" Command="{Binding NewGameCommand}" />
10
Trevy Burgess