WPF Projektseite per VB ansprechen

  • WPF

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von larihinz.

    WPF Projektseite per VB ansprechen

    Hallo an alle,

    ich würde mich über eine kleine Hilfestellung zum Thema XAML und VB freuen.

    Ausgangssituation : Ein WPF-Projekt, bestehend aus einer Seite Namens Aufbau.xaml und einer Seite namens Steuerung.xaml. Die Seite Aufbau enthält zwei Frames. In den ersten Frame wird die Seite Steuerung geladen und in den zweiten Frame sollen dann während der Laufzeit die verschiedenen Inhaltsseiten mit der Geschäftslogik geladen werden. Auf der Seite Steuerung befinden sich verschiedene Button, die die Navigation erledigen sollen. Ziemlich simpler Aufbau also.

    Mein Problem : Wie kann ich nun von der Seite Steuerung aus per VB-Code auf den Frame der Seite Aufbau zugreifen um diesen eine neue Source zuweisen zu können.

    Ist wahrscheinlich ganz einfach, aber ich komme beim besten Willen nicht drauf. Ich möchte aus verschiedenen Gründen keine Hyperlinks verwenden (obwohl das diese Problemstellung umgehen würde).

    Vielen Dank schon mal im Voraus für die Hilfestellung.

    Gruß aus Bremen
    Absolut sicher.

    Ich programmiere in VS 2012. Das Hinzufügen von Seiten zu dem Projekt ist ein ganz offizielles Feature, ohne irgendwelche Tricksereien. Menü Projekt/Seite hinzufügen. Dasselbe gilt für das Frame-Control. Ist ganz normal im Werkzeugkasten enthalten. Ist dem Frame in HTML ähnlich. Das Frame-Control beinhaltet die Eigenschaft Source. Hierfür wird dann der Name einer XAML-Seite (einer durch Projekt/Seite hinzufügen erstellten) angegeben.
    Diese Seite wird dann in dem Frame dargestellt. Einfachste Art der Seitennavigation. Verwendet man Hyperlinks für die Navigation, braucht man nicht eine einzige Zeile VB-Code.

    Z.B.:

    XML-Quellcode

    1. ​<Hyperlink NavigateURI="Seite1.xaml" TargetName="Frame1"/>


    Hyperlinks möchte ich jedoch, wie gesagt, nicht verwenden. Ich möchte mittels CodeBehind von der einen Seite aus (in meinem Fall die Seite Steuerung.xaml) die Source-Eigenschaft eines Frames auf einer anderen Seite (hier die Seite Aufbau.xaml) einstellen. Leider weiß ich nicht, wie ich diese andere Seite ansprechen kann. Der Frame ist benannt und kann von der Seite auf der er sich befindet problemlos angesprochen werden.

    Irgendeine Idee ?
    jetzt hab ich kurz angeguckt, ja.
    Ist auch nicht anders: Diese Source-Property ist nicht fürs CodeBehind vorgesehen, sondern eher dazu da, dass man eine geeignete Viewmodel-Property daran bindet.

    Das ist insgesamt ein umfassendes Konzept, MVVM genannt, jdfs. mit olle CodeBehind befindeste dich auf der falschen Schiene.

    Ich probier mal was zu basteln...
    WOW !!!

    Also erstmal megaherzlichen Dank für Deine Mühe. Das haut mich grad total um.

    Ich hoffe, das kommt jetzt nicht falsch rüber, aber da ich bezüglich dieses Themas noch ziemlich am Anfang stehe, ist das meiste von dem was sich in dem Projekt befindet noch um einiges zu hoch für mich. Es wird wohl noch ein bisschen dauern, bis ich schnalle, wie ich Deine Hilfestellung richtig verwenden kann. Natürlich werde ich mich demnächst detaillierter damit auseinander setzen. Ich hatte aber ehrlich gesagt auf einen eher simplen Hinweis bezüglich der Source-Property gehofft. Eine ganz simple Navigation hatte ich mir nämlich auch schon zurechtgebastelt.

    Über das MVVM-Konzept habe ich bereits ein bisschen gelesen, aber leider noch nicht so detailliert, dass ich irgendwas davon anwenden könnte, zumindest bis jetzt.

    Das Zugreifen auf die Property ist vb-technisch überhaupt kein Problem, wenn ich mich im Code in der selben Seitenklasse befinde.

    VB.NET-Quellcode

    1. ​Me.MainFrame.Source = New Uri("Seite21.xaml", UriKind.Relative)


    Auch wenn dieser Weg vielleicht nicht gerade elegant ist und eher eines Anfängers würdig, muss es doch eine Möglichkeit geben, auch von einer anderen Seite als der, in der sich der Frame befindet, auf den gewünschten Frame zugreifen zu können.
    Gibt es denn nicht innerhalb der Application eine Art Pages-Auflistung aus der ich mir die gewünschte Seite herauspicken kann ? Oder gibt es vielleicht eine Möglichkeit den besagten Frame so öffentlich zu machen, dass ich auch von einer anderen Seitenklasse heraus darauf zugreifen kann ?

    Klingt vielleicht ein bisschen laienhaft, aber ich hoffe, ich habe mich verständlich gemacht.

    Gruß aus Bremen

    larihinz schrieb:

    Gibt es denn nicht innerhalb der Application eine Art Pages-Auflistung aus der ich mir die gewünschte Seite herauspicken kann ?
    Nein, nicht dass ich wüsste.

    larihinz schrieb:

    Oder gibt es vielleicht eine Möglichkeit den besagten Frame so öffentlich zu machen, dass ich auch von einer anderen Seitenklasse heraus darauf zugreifen kann ?
    Sowas würde der Wpf-Architektur widersprechen, und es gibt auch keinen Grund, von "Seitenklassen" aus in einen Frame zu grabschen.
    In Wpf hat man ein Viewmodel, und im Idealfall weiß das überhaupt nix vom View, der sich daran bindet. Also generell nicht ins View grabschen, sondern Databindable Properties bereitstellen - das View kann dann daran anbinden.
    Hier sieht das konkret so aus:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Collections.ObjectModel
    3. Public Class MainModel : Inherits MainModelBase(Of MainModel)
    4. Private __Pages As New ObservableCollection(Of Uri)
    5. Public Property Pages() As ICollectionView = CollectionViewSource.GetDefaultView(__Pages)
    6. Public Sub New()
    7. For Each s In "Page1.Xaml Page2.Xaml Page3.Xaml".Split
    8. __Pages.Add(New Uri("pack://application:,,,/PageNavigation;component/View/" & s))
    9. Next
    10. End Sub
    11. End Class
    Das ist doch wirklich maximal einfacher Code, oder?
    Es gibt nur eine Property, und das ist eine CollectionView mit den Uris drinne.
    Eine CollectionView ist prinzipiell eine Liste, und zusätzlich ist eine Auswahl-Verwaltung eingebaut.

    XML-Quellcode

    1. <Window x:Class="MainWindow"
    2. DataContext="{Binding Source={StaticResource Mainmodel}}">
    3. ...
    4. <ListBox ItemsSource="{Binding Pages}" IsSynchronizedWithCurrentItem="True"/>
    5. <Frame Grid.Column="2" Source="{Binding Pages/}"/>
    6. </Window>
    Im View das Window bindet seinen DataContext ans Mainmodel.
    Der Navi-Bereich ist nun einfach eine Listbox, die an die o.g. Listen-Property bindet, und alle Uris anzeigt.
    Wähl in der Listbox einen aus, dann wird der ausgewählte in den Page-Frame geladen, denn der Page-Frame hat seine DataSource an dieselbe CollectionView gebunden, aber an die Auswahl-Funktionalität.
    Fertig - mehr muss der Frosch nicht kosten :D

    Ich würde dir empfehlen, dich soweit einzuarbeiten, dass du das verstehst.
    Sonst endest du wahrscheinlich mit irgendeine Wurstel-Lösung, und gewöhnst dir sehr sehr schlechte Gewohnheiten an.

    Wenn du Fragen hast, kannst du ja fragen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Der Code ist so einfach, den verstehe sogar ich, zumindest was die Vorgehensweise betrifft. Wenn ich Deinen Code allerdings 1 zu 1 übernehme, bekomme ich folgende Fehlermeldungen :

    VB : Der Typ MainModelBase ist nicht definiert.
    XAML : Die Resource "MainModel" konnte nicht aufgelöst werden.

    Ist sicherlich mein Fehler, aber was habe ich vergessen ?
    jaaa!

    Ich kann natürlich nicht an MainModel binden, so wie du's siehst, denn was ich gezeigt habe ist eine Klasse, keine Instanz. Die Instanz habe ich in den Resourcen von Application.Xaml angelegt, und schnöderweise genauso benannt wie den Klassennamen.
    Die Resourcen der Application.Xaml sind in allem Xaml sicht- und bindebar.

    Du musst halt Wpf verstehen, wie sowohl die Resourcen sich durch die Hierarchie vererben, aber auch die DataContexte.
    Guck auch mal im Wpf-Tut-Bereich herum, da werden so einige Facetten angeleuchtet.
    Und ein Thread hat auch viele Links auf weitere Tuts (aber meist englisch), und Bücher.
    Sorry für die späte Rückantwort, war unterwegs.

    ErfinderDesRades schrieb:

    Ich kann natürlich nicht an MainModel binden, so wie du's siehst, denn was ich gezeigt habe ist eine Klasse, keine Instanz.


    Na da habe ich mich ja erneut als Newbie geoutet. Mit ein bisschen Nachdenken hätte ich da ja auch selbst drauf kommen können. Danke also für den Anstoß. Ich merke, da gibt es noch einiges zu lernen.

    Kannst Du entsprechende Bücher empfehlen ? Weiß gar nicht, ob das hier überhaupt erlaubt ist. Falls nicht, bitte einfach überlesen.

    Gruß aus Bremen
    Bücher im Allgemeinen finden sich hier: Entwickler-Ressourcen und Tools, Bücher und WebCasts

    Weiß grad nichtmal, ob da Wpf-Bücher dabei sind. Aber bei Wpf muss man besonders Grundlagen-Sattelfest sein, Enums, Shared Members, generischen Delegaten sollte man mit Leichtigkeit und nach Belieben einzusetzen wissen.

    Zu Wpf guck doch den Wpf-Tut-Bereich durch - da ist mindest auch 1 Thread dabei mit Hinweisen zur Selbst-Bildung - ach, das sagte ich ja schon!