2013-04-30 3 views
4

J'ai un problème avecGetAdornerLayer retour null

AdornerLayer AdornerLayer = AdornerLayer.GetAdornerLayer (mise en page);

Cette méthode renvoie toujours la valeur null.

Qu'est-ce que je fais mal?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     Layout layout = new Layout(); 
     layout.Background = Brushes.White; 
     layout.ClipToBounds = true; 
     layout.SnapsToDevicePixels = true; 
     layout.Width = 4965; layout.Height = 3515; 

     AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(layout); 
     adornerLayer.Add(new LayoutAdorner(layout)); 
    } 
} 


public class Layout : Canvas 
{ 
    public Visual GetVisualChildAtPoint(Point point) 
    { 
     return VisualTreeHelper.HitTest(this, point).VisualHit as Visual; 
    } 
} 

public class LayoutAdorner : Adorner 
{ 
    public LayoutAdorner(UIElement adornedElement) : base(adornedElement) { } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 

    } 
} 

Répondre

5

Le AdornerLayer de la fenêtre ne sera pas créé jusqu'à ce que la fenêtre est effectivement chargée et la poignée est créée. Plutôt que de placer cela dans le constructeur, vous devrez peut-être retarder et ajouter l'adorner lorsque la fenêtre est chargée à la place. Une fois le formulaire actualisé, appelez Content.UpdateLayout();

+0

Merci vous pour ta réponse. Comment voulez-vous dire cela? – user2296810

+0

@ user2296810 Déplacez le code de l'adorateur dans l'événement Loaded - voir http://stackoverflow.com/questions/651013/why-to-run-code-in-method-called-by-xaml-window-loaded pour la plomberie il y –

+0

j'ai créé un bouton, donc la fenêtre est créée mais elle ne fonctionne pas private void button1_Click (expéditeur d'objet, RoutedEventArgs e) { Layout layout = new Layout(); layout.Background = Brosses.White; layout.ClipToBounds = true; layout.SnapsToDevicePixels = true; layout.Width = 4965; disposition.Hauteur = 3515; AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer (disposition); adornerLayer.Ajouter (nouveau LayoutAdorner (layout)); } – user2296810

0

(vieille question, mais je suis face à ce problème et ne pas trouvé une solution) AdornerLayer. GetAdornerLayer recherche un AdornerLayer dans l'arborescence visuelle vers le haut.

Dans le constructeur, l'arborescence visuelle n'est pas composée. Vous devez mettre votre code dans l'événement Window.Loaded.

Autre problème:

Layout layout = new Layout(); ... AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(layout);

La recherche est à la hausse. Mais la «mise en page» est le top (pas de parent). GetAdornerLayer retourne alors null. Pour obtenir le AdornerLayer de Windows, vous devez prendre un composant dans Windows (pas dans la Fenêtre, parce que c'est le haut de la fenêtre). Ma solution est le nom du premier Composant en 'root' XAML:

AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.root);

modifier:

Cette méthode peut retourner la couche de Adorner de certains types d'éléments WPF:

//If no adorner layer is found, return null 
private static AdornerLayer GetAdornerLayer(Visual visual) 
{ 
     var decorator = visual as AdornerDecorator; 
     if (decorator != null) 
      return decorator.AdornerLayer; 
     var presenter = visual as ScrollContentPresenter; 
     if (presenter != null) 
      return presenter.AdornerLayer; 
     var visualContent = (visual as Window)?.Content as Visual; 
     return AdornerLayer.GetAdornerLayer(visualContent ?? visual); 
} 
+0

Pouvez-vous ajouter d'autres explications sur la façon de "prendre un composant"? J'ai le même problème. Merci – CyberFox

+0

Voir l'édition dans ma réponse – Orwel

+0

Ok merci qui m'a aidé. Donc, si l'inférence de type échoue, vous n'avez qu'à demander un enfant afin que GetAdornerLayer() puisse effectuer une recherche vers le haut. Juste pour une petite correction, vous avez une variable redondante "window1". – CyberFox