WPF LogicalTree Ein-aushängen von elementen!



  • Hallo Leute,

    ich habe ein GroupControl , welches als TemplatePart ein Canvas enthält, um auf diese Canvas zugreifen zu können überschreibe ich die OnApplyTemplate() Methode in diesem Control und mache mir ein member _canvas!

    public override void OnApplyTemplate()
    		{
    			base.OnApplyTemplate();
    
    				_canvas = Template.FindName("PART_CanvasContent", this) as Canvas;
    		}
    

    So nun habe ich dieses GroupControl in einem weitern Canvas als Child eingefügt!

    Wenn ich nun diese nun wieder aus dem Canvas rausnehmen , und wieder neu einsetze! sind plötzlich alles Child GroupControl nicht mehr sichtbar!

    Als lösung habe ich die OnApplytemplate() im GroupControl folgender Workaorund:

    public override void OnApplyTemplate()
    		{
    			base.OnApplyTemplate();
    
    			if (_canvas != null)
    			{
    				var tmp= _canvas.Children.Cast<ViewItemBase>().ToArray();
    				_canvas.Children.Clear();
    				_canvas = Template.FindName("PART_CanvasContent", this) as Canvas;
    				tmp.ToList().ForEach(Hook);
    			}
    			else
    				_canvas = Template.FindName("PART_CanvasContent", this) as Canvas;
    		}
    

    woran liegt das denn? das ich die children des GroupControl neu initalisieren muss?



    1. Seitenfrage: Wieso konvertierst Du tmp erst zum Array, machst nichts damit und dann weiter zur ToList()?

    Das Removen des Templates führt vielleicht dazu das den Baum absägst.
    Setze ein Break Point im VS und gehe die Items in der Canvas einzeln durch, bestimme die Pos deines Templates und schau mal ob die ganze Liste gekillt wird oder nur nachfolgende Items.

    Nutze die evt, Fkt. remove[index];



  • Servus,

    ja das ToArray() ist sinnlos stimmt!

    hab ich schon probiert, ohne den Workaround, bleiben die Elemente in den Canvas drin, werden aber nich mehr angezeigt, erstr wenn ich sie eben wieder entferne und neu einfüge sind sie wieder da?

    Dadurch dass ich das control indem eben der canvas drin ist, aus dem Viusaltree rausnehmen und weider reinehmen ensteht der effekt!



  • Sag mal, hast Du irgendwo

    static
    

    in den Darstellungsebenen und vielleicht nicht auf alle Bereiche ausgedehnt - Klassen, Methoden, Attribute etc. ??
    Das riecht förmlich nach dem Klassiker ... 😉



  • nein nix mit static:)

    Hier nochmal der Pseudo Code zu dem Problem:

    [TemplatePart(Name = "PART_CanvasContent", Type = typeof(Canvas))]
    	public class ViewGroupItem : ViewItemBase
    	{
    		static ViewGroupItem()
    		{
    			DefaultStyleKeyProperty.OverrideMetadata(
    				typeof(ViewGroupItem), new FrameworkPropertyMetadata(typeof(ViewGroupItem)));
    
    		}
    ....
    
    private Canvas _canvas;
    
    public override void OnApplyTemplate()
    		{
    			base.OnApplyTemplate();
    
    			if (_canvas != null)
    			{
    				var tmp = _canvas.Children.Cast<ViewItemBase>().ToList();
    				_canvas.Children.Clear();
    				_canvas = (GetTemplateChild("PART_CanvasContent") as Canvas);
    				tmp.ForEach(it => _canvas.Children.Add(it));
    			}
    			else
    				_canvas = Template.FindName("PART_CanvasContent", this) as Canvas;
    
    		}
    
    ....
    }
    

    Szenario im Ablauf: (Pseudo)

    var host= ne Canvas();
    
    var group= ViewGroupItem();
    
    host.Children.Add(group);
    group.ApplyTemplate(); 
    //ApplyTemplate: Hier ist nun der Canvas des ViewGroupItem Instanz initaliert, GetTemplateChild würde hier eine "null" liefeen, wenn die grup noch in keinem visual tree eingehängt ist
    
    group._canvas.Add(new ControlFoo());
    group._canvas.Add(new ControlBar());
    // Nun werden zwei elemente in dem canvas des ViewGroupItems eingefügt! Und wird auch schön angezeugt!
    
    //Nun hänge ich das GroupViewItem wieder aus dem host aus!
    host.Remove(group);
    
    //Und hänge es wieder ein! 
    host.Add(group);
    
    //So nun ist die _canvas referenu des GroupViewItems noch da und die element vorhanden, werden aber nicht mehr angezeigt
    
    jetzt m,usst ich erneut ApplyTemplate() ausführen, die Controls des canvases mit merken , canvas referenz mit GetTemplateChild  neu holen, und kinder wieder einfügen!
    

    hilft das?=



  • Bin ich blind oder steht da dick static dran im Ctor von ViewGrpItem? 🙄
    Der nebenher auch noch internal ist...



  • hmmm ACHSO ich dachte statische member!

    Aber was hat der statische Konstruktor aufruf mit dem Problem zu tun, da sag ich ja nur, dass der Control style/theme im generic.xmal zu finden ist!?

    Oder stellt das ein problem da?



  • static ViewGroupItem() 
             { 
                 DefaultStyleKeyProperty.OverrideMetadata( 
                     typeof(ViewGroupItem),
    
    // => hier knallt es!
     new FrameworkPropertyMetadata(typeof(ViewGroupItem)));
    

    new FrameworkFrameworkPropertyMetadata läuft unter static und damit kannst beim zweiten Aufruf(Objektbildung) nur noch auf die Datenstruktur zugreifen und mit new nicht mehr überschreiben! Du bildest kein Objekt. Siehe im Buch zu Schüsselwort static! 🕶

    Siehe Dir mal meine "triviale" Lösung an:

    public partial class BuildCanvas_Mediator
        {
    
            public BuildCanvas_Mediator()
            {                                 
                this.canvas2 = canvas1;            
            }
    
            public Canvas canvas2;
            public static Canvas canvas1 = new Canvas();
    ...
            public void SetCanvasSetting()
            {]
    ..   
            public bool AddPolygonAroundMarkedText(TextSelection textSel)
            {
    ..
            }
    
            private static void CallFeatueDefinition(string Text)
            {
    ...
            }
    

    http://de.wikipedia.org/wiki/Vermittler_(Entwurfsmuster)

    Aufrufer in multiversen Instanzen:

    public partial class AffinityText : Page
        {
            public AffinityText()
            {
                InitializeComponent();                      
            }
    
            public BuildCanvas_Mediator bc_med = new BuildCanvas_Mediator();      
            private bool canvasAdded;
    
            public static readonly RoutedUICommand MarkingText =
                new RoutedUICommand("MarkingText", "Quelle markieren", typeof(AffinityText));
    
            private void MarkingText_CanExecute (object sender, CanExecuteRoutedEventArgs rea)
            {
                rea.CanExecute = true;
                rea.Handled = true;
            }
    
            private void MarkingText_Execute(object sender, ExecutedRoutedEventArgs rea)
            {
                TextSelection docSelect = FirstDoc.Selection;
    
                bc_med.AddPolygonAroundMarkedText(docSelect);
                if (canvasAdded == false)
                {
                    markings_aff.Children.Add(bc_med.canvas2);
                    canvasAdded = true;
                }
            }
    


  • Hmmm das verstehe ich jetzt nich ganz, Objekte vom Type ViewItemGroup hab ich mehrere.. der statische Konstruktur sagt ja dem WPF Framework nur "EINMAL" dass das Theme Resource zu dem Control in dem std. generic.xmal verwießen wird!

    Einen statisceh canvas bringt mir nix, weil eben viele ViewItemGrup instanzen ihre eigenen Canvas haben, sich sogar hierachisch aufbauen!

    Also wieso es an der Stelle knallt die du beschreiben ahst versteh ich nicht, die wird ja auch nur einmal aufgerufen.... das dürfte dem VisualTree nich interessieren!?:)



  • Ach du meinst in meinen Pseudo code ,da habe ich bei

    var group= ViewGroupItem();
    

    das "new" vergessen! meinst du deswegen?

    soll schon

    var group= new ViewGroupItem();
    

    heißen!

    ich instanziiere das object schon mehrmals.



  • Neiiiin! 🙄
    Du instanzierst keine Objekte.
    Du referenzierst den Ctor als Data über bestehende Zeiger! - Diese bleiben zur Laufzeit erhalten. Mit remove & add serviert er dir immer wieder die gleichen Zeiger zum alten Heap.
    Schau ins Buch! Egal, ob C, C#, C++ oder Java.



  • Ich hab das konzeot von static schon verstanden!

    Aber WAS hat der Inhalt im statischen Konstruktor mit meinen Canvas instanzen zu tun?

    Der Imhalt soll ja nur einmal aufgerufen werden, damit die WPF laufzeit weiß, dass mein GroupViewItem eben Themens im generic.xaml verwendet. mehr nicht!

    bei erzeugung des Objekts, wird via ApplyTemplatey für jede Instanz eine _canvas instanz erzeugt und fertig... !?!

    entweder ich steh aufm schlauch, oder du:=)



  • SORRY mein fehler!

    ich hab nur code schnippsel der Klasse gepostet.. ich hab natürlich auch einen nicht statuschen Konstruktur, der bei der instanziierung verwendet wird!

    Sorry das war jetzt verwirrend:)

    also kann es an dem statische Konstruktir nich liegen...



  • NullBockException schrieb:

    SORRY mein fehler!

    ich hab nur code schnippsel der Klasse gepostet.. ich hab natürlich auch einen nicht statuschen Konstruktur, der bei der instanziierung verwendet wird!

    Sorry das war jetzt verwirrend:)

    also kann es an dem statische Konstruktir nich liegen...

    Fehler 3 : Zugriffsmodifizierer sind bei statischen Konstruktoren nicht zulässig.

    Das passiert, wenn Du die Überladung mit einen leeren statischen Ctor versuchst.

    Ich habe daher kein Bock mehr auf Dich. 👎



  • Tut mir Leid, du hast das Problem nicht verstanden! Wenn ich den statischen Ctor rausnehme besteht das Problem weiter hin...

    Schönen Abend


Log in to reply