Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   .NET-Framework (managed code) (https://www.delphipraxis.net/79-net-framework-managed-code/)
-   -   C# TreeView als Navigation nutzen - Welche Herangehensweise bei WPF? (https://www.delphipraxis.net/155115-treeview-als-navigation-nutzen-welche-herangehensweise-bei-wpf.html)

Mithrandir 9. Okt 2010 14:23

TreeView als Navigation nutzen - Welche Herangehensweise bei WPF?
 
Hi ihr,

ich stehe gerade aufm Schlauch. Ich möchte auf der linken Seite meiner Anwendung eine TreeView als Navigationsleiste haben. Dabei soll sich auf der rechten Seite, je nach gewähltem Punkt, die dargestellte Maske ändern. Unter Delphi hätte ich es so gemacht: TreeView auf das Formular, Splitter daneben, dann n PageControl und die entsprechenden Seiten, dabei die Tabs ausblenden. Fertig. Dann müsste man nur noch programmatisch beim Klick aufs TreeView die passende Seite aktiv setzen.

Jetzt habe ich aber XAML und CSharp vor mir, und fühl mich etwas verloren. Ich habe mir überlegt, für jede meiner Masken eine eigene XAML-Datei zu definieren. Das hab ich bei der Controlleiste, beim TreeView (Navigation) und beim Hauptbereich der Anwendung auch schon getan. Dies sieht dann so aus:

Exemplarisch die ControlBarView.xaml:
XML-Code:
<UserControl x:Class="SmallTune.View.ControlBarView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="Auto" Width="Auto">
    <Grid>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="29" />
        <CheckBox Content="CheckBox" Height="16" HorizontalAlignment="Left" Margin="43,4,0,0" Name="checkBox1" VerticalAlignment="Top" />
    </Grid>
</UserControl>
Anschließend die MainWindow.xaml:
XML-Code:
<Window x:Class="SmallTune.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:View="clr-namespace:SmallTune.View"
        Title="SmallTune.NET" Height="350" Width="525" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="354*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="34*" />
            <RowDefinition Height="277*" />
        </Grid.RowDefinitions>
        <View:ControlBarView Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"></View:ControlBarView>
        <View:NavigationSideBarView x:Name="NavigationSideBarView" Grid.Column="0" Grid.Row="1"></View:NavigationSideBarView>
        <View:PlayListView x:Name="PlayListView" Grid.Column="1" Grid.Row="1"></View:PlayListView>
    </Grid>
</Window>
Ich binde den View-Namespace ein und zeige dann die Usercontrols in den verschiedenen Grids an. Was ich jetzt möchte, ist, dass bei Klick auf ein TreeViewItem ein anderes UserControl angezeigt wird, was sich im Namespace SmallTune.View befindet. Wie löse ich das mit XAML unter Beibehaltung der Trennung von Code und Design? :gruebel:

Khabarakh 9. Okt 2010 17:21

AW: TreeView als Navigation nutzen - Welche Herangehensweise bei WPF?
 
Fangen wir mal mit der ViewModel-Ebene an: In einem zentralen VM (ob MainVM oder NavigationBarVM oder vielleicht sogar beide doch lieber in einer Klasse ist eher Geschmackssache) bräuchten wir erst einmal das VM, das dann rechts angezeigt werden soll:
Code:
public ContentViewModel SelectedContent { get; set; }
Dabei habe ich zur Übersicht eine Basisklasse für alle entsprechenden VMs eingeführt, auch wenn sie wahrscheinlich gar keinen Code enthalten wird.
Diese Property können wir sofort binden:
Code:
<ContentPresenter Content="{Binding SelectedContent}" />
Da aber ein DataTemplate kaum für alle ContentVMs passen wird, geben wir es nicht explizit an, sondern benutzen Implicit Data Templates:
Code:
<DataTemplate DataType="{x:Type vm:SomeContentViewModel}">
    <view:SomeContentView />
</DataTemplate>
Das muss entweder in die Ressourcen der gleichen XAML-Datei oder in App.xaml. Einfache Templates könntest du auch direkt darin deklarieren, aber der Übersichtlichkeit halber sind UserControls sicher keine schlechte Idee :) .

TreeView+MVVM ist grundsätzlich klar? Kurz skizziert braucht jedes VM eines TreeViewItems eine Eigenschaft
Code:
ContentViewModel Content { get; private set; }
Dann kannst du die beiden verbinden:
Code:
<TreeView SelectedValue="{Binding SelectedContent}" SelectedValuePath="Content" />
Edit: WTF, warum ist das XML-Code-Tag inline :gruebel: ? Das muss ich wohl mal nachlesen. Erledigt, ich bleib wohl erstmal bei den schmucklosen Dingern ;) .

Mithrandir 9. Okt 2010 19:54

AW: TreeView als Navigation nutzen - Welche Herangehensweise bei WPF?
 
Yeah, danke schön. :) Klingt einleuchtend. Wenn man einmal dahinter gestiegen ist, macht die ganze Geschichte sogar richtig Spaß... :)

Mithrandir 6. Dez 2010 22:06

AW: TreeView als Navigation nutzen - Welche Herangehensweise bei WPF?
 
Sebastian, irgendwie stehe ich doch auf dem Schlauch. WPF erfordert irgendwie eine komplett neue Denkweise, die mich momentan noch überfordert.

Ich habe das MVVM Pattern aufgeweicht und durch ein MVC-Pattern mit Mediator ersetzt. Damit komme ich besser zurecht. Auch nutze ich die Codebehind-Datei, da ich bspw. damit überfordert bin, bei einer Listview im ViewModel/Controller auf einen Doppelklick auf ein Item zu reagieren. Ich habe mir hier Attached Command Behaviour von Marlon Grech angesehen, bekomme aber eine Fehlermeldung, dass ein Objekt nicht erstellt wurde... :gruebel:

Ich dachte im Oktober, ich habs verstanden, aber heute merke ich... Nö.

Ich habe mir jetzt meine UserControls erstellt, die ich anzeigen möchte. Jedes UC hat eine Controller-Klasse, die dem DataContext des jeweiligen Views zugewiesen sind. Ähm... Wie gehts jetzt weiter? :gruebel: Ich muss ja im TreeviewItem auf den Klick reagieren. Ist das egal, ob ich das TVItem im Controller erstelle oder im XAML? Mein TreeView sieht jetzt so aus:

Code:
<TreeView>
  <TreeViewItem Name="tviOverview" Header="Übersicht" />
  <TreeViewItem Name="tviLibrary" Header="Bibliothek" />
  <TreeViewItem Name="tviMood" Header="Mood" />
  <TreeViewItem Name="tviMap" Header="Map" />
</TreeView>
Ich verstehe jetzt jedenfalls, warum sich WPF noch nicht so richtig durchgesetzt hat. Die Lernkurve ist, trotz Literatur doch... gewaltig.

Mithrandir 7. Dez 2010 14:32

AW: TreeView als Navigation nutzen - Welche Herangehensweise bei WPF?
 
Ok, ich habs hinbekommen... Sehr geil... :firejump: :firejump:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz