Laden...

[gelöst] Frage zu Adornern (WPF)

Erstellt von nordside vor 16 Jahren Letzter Beitrag vor 16 Jahren 3.127 Views
nordside Themenstarter:in
186 Beiträge seit 2007
vor 16 Jahren
[gelöst] Frage zu Adornern (WPF)

Hallo,

Ich verwende Adorner dazu, dass Aussehen von grafischen Bedienelementen zur Laufzeit durch den Benutzer ändern zu lassen.

Dies habe ich erfolgreich ausprobiert. Ein Canvas dient mir dabei als Layer und WrapPanels waren die zu manipulierenden Bedienelemente. Jetzt habe ich das Canvas in ein TabControl untergebracht - und es geht nichts mehr. Die Ursache ist, dass die Anweisung


layer = AdornerLayer.GetAdornerLayer(myCanvas); //

Probleme bereitet. Solange das Canvas direkt auf der Page lag, funktionierte es. Jetzt ist es in das TabControl untergeordnet - und liefert null zurück. Der Aufruf dieser Anweisung erfolgt wenn das Ereignis Loaded der Page ausgelöst wird.

Vielen Dank
nordside

nordside Themenstarter:in
186 Beiträge seit 2007
vor 16 Jahren

Hallo,

zur Veranschaulichung habe ich ein Projekt angehangen. Im oberen Teil ist ein TabControl mit zwei TabItems angelegt. Jedes der TabItems besitzt jeweils ein Canvas mit je einem WrapPanel, das durch Code hinzugefügt wurde. Im unteren Teil ist nur ein Canvas mit einem WrapPanel.

Durch Adorner habe ich die WrapPanels so erweitert, dass zu Laufzeit die Größe/Lage geändert werden kann. Startet man das Programm, funktioniert das auch - sowohl mit dem WrapPanel im TabControl->Canvas, als auch mit dem WrapPanel direkt auf dem Canvas.

Klickt man auf den Reiter "TI2" sieht man ebenfalls ein Canvas mit WrapPanel - nur bei diesem funktioniert das nicht - nur die Lage kann geändert werden. Geht man zurück auf den Reiter "TI1" funktioniert es hier auf einmal auch nicht mehr. Grund dafür ist, dass die Thumbs zur Größenänderung nicht angezeigt werden. Die Anzeige der Thumbs wird in der Klasse ResizingAdorner gesteuert - habe dort jedoch keinen Fehler gefunden.

Nur bei dem WrapPanel auf dem Canvas, das nicht in einem TabControl angeordnet ist funktioniert es immer.

Ich bin ziemlich ratlos - ich hoffe jemand hat eine Idee
nordside

140 Beiträge seit 2007
vor 16 Jahren

Hallo nordside,
ich kann dein Beispiel leider erst gar nicht kompilieren....
Könntest du bitte die Datei noch mal uploaden - bitte lösche aber diesmal die Solution NICHT. Obwohl, daran liegt es ja mit sicherheit nicht....

Viel Erfolg (mit wenig Aufwand),
Sisyphus

140 Beiträge seit 2007
vor 16 Jahren

Nee, brauchst nicht -> ich hab das alles in ein neues Project rein kopiert, jetzt kann ichs...

Komisch, der Effekt - ich schau mal nach.

Viel Erfolg (mit wenig Aufwand),
Sisyphus

140 Beiträge seit 2007
vor 16 Jahren

a) myTCLayer2 wird nirgendwo verwendet -> siehe
WrapPanel myTCWrapPanel2 = new WrapPanel();
....

Viel Erfolg (mit wenig Aufwand),
Sisyphus

nordside Themenstarter:in
186 Beiträge seit 2007
vor 16 Jahren

typischer Copy/Paste-Fehler X(


WrapPanel myTCWrapPanel2 = new WrapPanel();
myTCWrapPanel2.Height = 20;
myTCWrapPanel2.Width = 20;
myTCWrapPanel2.Margin = new Thickness(20);
myTCWrapPanel2.Background = new SolidColorBrush(Colors.Blue);
myTCCanvas2.Children.Add(myTCWrapPanel2);
try
{
  myTCLayer2.Add(new ResizingAdorner(myTCWrapPanel2));
}
catch (Exception ex)
{
  lblMsg.Content = ex.Message;
}

Hier wird dann auch eine Exception geworfen:

"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

Dies bezieht sich auf die Variable myTCLayer2. Aber warum? TCLayer und TCLayer2 initialisiere ich identisch:

            
myTCLayer = AdornerLayer.GetAdornerLayer(myTCCanvas);
myTCLayer2 = AdornerLayer.GetAdornerLayer(myTCCanvas2); 

140 Beiträge seit 2007
vor 16 Jahren

b) scheinbar kannst du den Verweis auf AdornerLayer.GetAdornerLayer(Canvas) nur dann bekommen, wann der Canvas "sichtbar" ist -> deswegen wäre mein Vorschlag die Adorner in tcUser.SelectionChanged gründlich zu debuggen, was da null ist und was nicht.

Viel Erfolg (mit wenig Aufwand),
Sisyphus

140 Beiträge seit 2007
vor 16 Jahren

P.S. (zum Editierten Beitrag) Zur Laufzeit ist nur EIN Tab aktiv, bzw. nur ein Canvas ist sichtbar.

Viel Erfolg (mit wenig Aufwand),
Sisyphus

140 Beiträge seit 2007
vor 16 Jahren

laut MSDN "Using Extensible Application Markup Language (XAML) to bind an adorner to another element is currently not supported." und "GetAdornerLayer walks up the visual tree, starting at the specified UIElement, and returns the first adorner layer it finds. (If no adorner layers are found, the method returns null.)" etc. wird der AdornerLayer immer zurückgesetzt, sobald der Steuerelement aus der Sicht verschwindet -> wie gesagt, scheinbar solltest du alle Adornern in tcUser.SelectionChanged ständig neu aktualisieren. So viel dazu meinerseits.

Viel Erfolg (mit wenig Aufwand),
Sisyphus

nordside Themenstarter:in
186 Beiträge seit 2007
vor 16 Jahren

DANKE!!!!

Wenn das Canvas bei den TabItems geladen wird (Ereignis "Loaded") weise ich die Adorner-Eigenschaft zu - und es funktioniert!!!!

Die Woche ist gerettet 🙂
nordside