Binding prozedural erstellen

  • WPF

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von seh.

    Binding prozedural erstellen

    Hallo,

    @Nofear23m gab mir in einem anderen Thread schon ein Sample-Projekt mit einer simplen Standardimplementierung eines ServiceContainers mit Services wie IWindowService welche dazu da sind, Fenster in der WPF zu erstellen/öffnen und zu schließen.

    In diesem Sample Projekt gibt es ein MyDefaultWindow welches den folgenden Inhalt hat:

    XML-Quellcode

    1. <Window x:Class="MyDefaultWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:App"
    7. mc:Ignorable="d"
    8. Title="MyDefaultWindow" Height="185.911" Width="486.335">
    9. <ContentPresenter Content="{Binding}"/>
    10. </Window>


    Ich versuche aktuell von dem XAML wegzukommen und das Window mit dem ContentPresenter und seinem Binding prozedural zu erstellen.
    Meine WindowService Klasse sieht aktuell so aus:

    C#-Quellcode

    1. public class WindowService : IWindowService
    2. {
    3. public void Create<TViewModel>() where TViewModel : ViewModelBase, new()
    4. {
    5. var window = new System.Windows.Window
    6. {
    7. DataContext = new TViewModel(),
    8. Content = new ContentPresenter()
    9. {
    10. Content = new Binding()
    11. }
    12. };
    13. window.Show();
    14. }
    15. public void Destroy<TViewModel>() where TViewModel : ViewModelBase
    16. {
    17. foreach(System.Windows.Window window in Application.Current.Windows)
    18. {
    19. if (window.DataContext.GetType() == typeof(TViewModel))
    20. window.Close();
    21. }
    22. }
    23. }


    Der Create()-Methode kann ich generisch das ViewModel übergeben, sodass ich den DataContext des Windows erstellen und zuweisen kann.
    Allerdings will das Binding vom ContentPresenter nicht funktionieren. Ich bin nicht sicher ob ich das prozedural so korrekt gemacht habe. Die Content-Eigenschaft vom ContentPresenter bindet sich ja an den Root. Bin mir aber unsicher ob ich das Binding so richtig konstruiere.

    In meiner App.xaml habe ich ein DataTemplate für mein View erstellt:

    XML-Quellcode

    1. <DataTemplate DataType="{x:Type viewmodels:MainViewModel}">
    2. <views:MainView />
    3. </DataTemplate>


    Wobei mein MainViewModel von der ViewModelBase erbt und mein MainView ist ein UserControl welches einen simplen Button enthält.
    Kompilieren tut alles, allerdings sieht mein Window wie folgt aus:



    Wahrscheinlich mache ich beim Binden einfach was falsch, vielleicht ist der leere Konstruktor nicht dasselbe wie das binden an den Root. Daher habe ich den zweiten Konstruktor von der Binding Klasse genommen und einfach einen leeren String übergeben, aber auch da komme ich auf das gleiche Ergebnis. Wie kann ich prozedural auf den Root binden?

    Edit: Ich habe das ganze mal auf meinem GitHub veröffentlicht. Die Struktur ist folgende. Das SlightLibs.WPF.Tests ist eine WPF Applikation in der ich die beiden anderen Bibliotheken referenziere. Ansonsten ist das Projekt von der Komplexität überschaubar und beinhaltet bis jetzt wirklich nur den Window Anzeige-Kram.
    Außerdem habe ich es jetzt doch noch mal mit dem DefaultWindow als XAML probiert und bekomme es selbst da nicht zum rendern. Was vergesse ich?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „seh“ ()

    seh schrieb:

    Ich versuche aktuell von dem XAML wegzukommen
    imo keine gute idee.
    Was hast du gegen Xaml?
    Grade Bindings lassen sich in Xaml wunnebar formulieren, während man Hirnkrämpfe kriegt, wenn man dasselbe prozedural hinzubasteln versucht.

    Benütze Xaml wofür es gedacht ist, und c# auch, wofür es gedacht ist.
    Sehr komisches Verhalten, ich habe die Ursache gefunden. Ich habe in der App.xaml keine StartupUri definiert weil ich das erste Window auch über meinen WindowService erstellen wollte. Sobald ich ein Window erstellt habe und dieses mit der StartupUri zuerst starten lasse, funktionieren alle SubViews mit meinem WindowService.

    Weiß einer warum sich das ganze so verhält?
    Hallo

    Wo hast du denn die DataTemplates definiert? Das Problem ist das die Resourcen evtl. mit deiner Variante nicht richtig greifen.
    Empfehlung von mir: Mach dir ein Window und packe dort in die Resourcen deine DataTemplates. UND mindestens ein Style!

    Guck dir mal meine Application XAML aus meinem Beispiel an. Ich habe dort einen Style für ein Rectangle vergeben. Es kann (leider) manchesmal dazu kommen das wenn in der Application.xaml (oder App.xaml in C#) nichts außer DataTemplates definiert wird diese dann nicht greifen. Warum kann ich dir auch nicht genau sagen, ich weis nur das es leider so ist.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m Ja, ich hatte mich an deiner App.xaml orientiert und dort dann auch die DataTemplates definiert.
    Aber das Style habe ich nicht übernommen. Ich probiere das mal aus und melde mich dann zurück. Bis jetzt hab ich es dann so gelöst das ich ein MainWindow mit der StartupUri geöffnet habe und alle subwindows dann mit dem Window Service. Wollte ursprünglich alle Fenster über den WindowService managen.
    Ich müsste das mal bei mir hier probieren, sollte eigendlich aber auch funktionieren.

    Probier mal und melde dich hald wieder, falls es nicht klappt mit meinem Tipp das versuche ich es hier mal bei mir.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Ich weis, das Verhalten ist merkwürdig und auch nicht 100%ig nachzuvollziehen. Ich habe es beireits versucht, bin aber auf keinen grünen Zweig gekommen, man kann es aber des öfteren im Netz nachlesen das es diese "Probleme" gibt. Meißt fällt es aber nicht auf da man ohnehin immer einige Styles definiert welche Programmweit greifen sollen und man somit das Problem erst gar nicht hat.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##