Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Certains aspects de l’initialisation de Windows Presentation Foundation (WPF) sont différés aux processus qui reposent généralement sur cet élément connecté à l’arborescence logique ou à l’arborescence visuelle. Cette rubrique décrit les étapes qui peuvent être nécessaires pour initialiser un élément qui n’est pas connecté à l’une ou l’autre arborescence.
Éléments et arborescence logique
Lorsque vous créez une instance d’une classe Windows Presentation Foundation (WPF) dans le code, vous devez savoir que plusieurs aspects de l’initialisation d’objet pour une classe Windows Presentation Foundation (WPF) ne font délibérément pas partie du code exécuté lors de l’appel du constructeur de classe. En particulier pour une classe de contrôle, la plupart de la représentation visuelle de ce contrôle n’est pas définie par le constructeur. Au lieu de cela, la représentation visuelle est définie par le modèle du contrôle. Le modèle provient potentiellement d’une variété de sources, mais le plus souvent, le modèle est obtenu à partir de styles de thème. Les modèles sont en fait à liaison tardive ; le modèle nécessaire n’est attaché au contrôle en question qu’une fois le contrôle prêt pour la disposition. Et le contrôle n’est pas prêt pour la disposition tant qu’il n’est pas attaché à une arborescence logique qui se connecte à une surface de rendu à la racine. Il s’agit d’un élément de niveau racine qui lance le rendu de tous ses éléments enfants tels que définis dans l’arborescence logique.
L’arborescence visuelle participe également à ce processus. De plus, les éléments qui font partie de l’arborescence d’éléments visuels par l’intermédiaire des modèles ne sont totalement instanciés que quand ils sont connectés.
Les conséquences de ce comportement sont que certaines opérations qui reposent sur les caractéristiques visuelles terminées d’un élément nécessitent des étapes supplémentaires. Par exemple, si vous tentez d’obtenir les caractéristiques visuelles d’une classe qui a été construite, mais pas encore attachée à une arborescence. Par exemple, si vous souhaitez appeler Render sur un RenderTargetBitmap et que le visuel que vous transmettez est un élément non connecté à une arborescence, cet élément n’est pas terminé visuellement tant que des étapes d’initialisation supplémentaires ne sont pas terminées.
Utilisation de BeginInit et endInit pour initialiser l’élément
Différentes classes de WPF implémentent l’interface ISupportInitialize. Vous utilisez les méthodes BeginInit et EndInit de l’interface pour indiquer une région dans votre code qui contient des étapes d’initialisation (telles que la définition de valeurs de propriété qui affectent le rendu). Une fois EndInit est appelée dans la séquence, le système de disposition peut traiter l’élément et commencer à rechercher un style implicite.
Si l’élément sur lequel vous définissez des propriétés est une classe dérivée FrameworkElement ou FrameworkContentElement, vous pouvez appeler les versions de classe de BeginInit et de EndInit plutôt que de passer à ISupportInitialize.
Exemple de code
L’exemple suivant est un exemple de code pour une application console qui utilise des API de rendu et XamlReader.Load(Stream) d’un fichier XAML libre pour illustrer le positionnement approprié de BeginInit et de EndInit autour d’autres appels d’API qui ajustent les propriétés qui affectent le rendu.
L’exemple illustre uniquement la fonction principale. Les fonctions Rasterize et Save (non affichées) sont des fonctions utilitaires qui prennent en charge le traitement d’images et les E/S.
[STAThread]
static void Main(string[] args)
{
UIElement e;
string file = Directory.GetCurrentDirectory() + "\\starting.xaml";
using (Stream stream = File.Open(file, FileMode.Open))
{
// loading files from current directory, project settings take care of copying the file
ParserContext pc = new ParserContext();
pc.BaseUri = new Uri(file, UriKind.Absolute);
e = (UIElement)XamlReader.Load(stream, pc);
}
Size paperSize = new Size(8.5 * 96, 11 * 96);
e.Measure(paperSize);
e.Arrange(new Rect(paperSize));
e.UpdateLayout();
/*
* Render effect at normal dpi, indicator is the original RED rectangle
*/
RenderTargetBitmap image1 = Rasterize(e, paperSize.Width, paperSize.Height, 96, 96);
Save(image1, "render1.png");
Button b = new Button();
b.BeginInit();
b.Background = Brushes.Blue;
b.Width = b.Height = 200;
b.EndInit();
b.Measure(paperSize);
b.Arrange(new Rect(paperSize));
b.UpdateLayout();
// now render the altered version, with the element built up and initialized
RenderTargetBitmap image2 = Rasterize(b, paperSize.Width, paperSize.Height, 96, 96);
Save(image2, "render2.png");
}
<STAThread>
Shared Sub Main(ByVal args() As String)
Dim e As UIElement
Dim _file As String = Directory.GetCurrentDirectory() & "\starting.xaml"
Using stream As Stream = File.Open(_file, FileMode.Open)
' loading files from current directory, project settings take care of copying the file
Dim pc As New ParserContext()
pc.BaseUri = New Uri(_file, UriKind.Absolute)
e = CType(XamlReader.Load(stream, pc), UIElement)
End Using
Dim paperSize As New Size(8.5 * 96, 11 * 96)
e.Measure(paperSize)
e.Arrange(New Rect(paperSize))
e.UpdateLayout()
'
' * Render effect at normal dpi, indicator is the original RED rectangle
'
Dim image1 As RenderTargetBitmap = Rasterize(e, paperSize.Width, paperSize.Height, 96, 96)
Save(image1, "render1.png")
Dim b As New Button()
b.BeginInit()
b.Background = Brushes.Blue
b.Height = 200
b.Width = b.Height
b.EndInit()
b.Measure(paperSize)
b.Arrange(New Rect(paperSize))
b.UpdateLayout()
' now render the altered version, with the element built up and initialized
Dim image2 As RenderTargetBitmap = Rasterize(b, paperSize.Width, paperSize.Height, 96, 96)
Save(image2, "render2.png")
End Sub
Voir aussi
- Arborescences dans WPF
- Vue d’ensemble du rendu graphique WPF
- XAML dans WPF
.NET Desktop feedback