none
Wie übergebe ich Daten aus mehreren Datagrids in einem UserControl in ein anderes UserControl in einem TreeView? RRS feed

  • Frage

  • Hallo,

    ich habe bereits nun viele Varianten rund um das TreeView ausprobiert. Ich komme jedoch nicht auf eine richtige Lösung.

    Problem:
    Ich habe in einem UserControl 3 Datagrids "Akten", "Vorgänge" und "Ergebnisse" die jeweils an eine SQL-Datenbank gebunden sind. Dafür habe ich entsprechende Classes in Model und ViewModel erstellt.

    Nun möchte ich die Datagrids in der Form auslesen und dann in ein TreeView in einem anderen UserControl darstellen, dass alle in den Datagrids markierten Zeilen entsprechend in das TreeView übertragen werden sollen. Hierachie:

    - Akten
         - Vorgänge
             - Ergebnisse

    Für das TreeView habe ich auch schon entsprechende Classen definiert, in denen die ChildMember als OberservableCollection definiert sind.

    Hat jemand hier eine Lösung parat, wie ich das realisieren kann, insbesondere das Übergeben der SelectedItems aus den Datagrids in die TreeView-Collections???

    Schon mal Dank für die Überlegungen.

    Gruß Jürgen

    Donnerstag, 28. Januar 2016 15:02

Antworten

  • Hallo Peter,

    vielen Dank für deine Überlegungen.

    Das Datenmodell ist ziemlich umfangreich und die Tabellen bestehen in bestimmten Beziehungen.

    Ich habe es jetzt aber über ein ViewModel für den TreeView hingekriegt.

    Gruß Jürgen

    • Als Antwort markiert Jürgen Sch Freitag, 5. Februar 2016 07:32
    Freitag, 5. Februar 2016 07:32

Alle Antworten

  • Hi Jürgen,
    Daten brauchst Du nicht übergeben, wenn sich die Oberfläche die Daten aus dem Datenpuffer selbst holt, z.B. im Ergebnis des Aufrufes eines PropertyChanges.

    Du lädst die Daten in ObservableCollections, die Du als Datenquelle für CollectionViewSources nutzt. Die View Eigenschaft kann dann für die Anzeige in den DataGrids genutzt werden. Wenn jetzt eine Datenzeile in einem DataGrid ausgewählt wird, übernimmst Du das CurrentItem im CurrentChanged Ereignis der Sicht für den Aufbau einer ObservableCollection, die dann als Datenquelle im TreeView genutzt wird. Das hört sich vielleicht etwas kompliziert an, ist aber in der Realisierung recht einfach.


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Donnerstag, 28. Januar 2016 21:26
  • Hallo Peter,

    schön, dass du dich einschaltest. Ich glaube, ich habe mein Konstrukt zu kompliziert aufgebaut.

    Als Beispiel stelle ich mal die Basis-Model-Klassen und die ViewModel-Klassen anhand der obersten Ebene "Akten" dar, sowie die UserControls, damit du dir einen Eindruck von meinem Konstrukt machen kannst:

    //BasisKlasse für oberste Ebene - Akten
    public class TvAkten
        {
            #region Properties
            public string AkteName { get; set; }
    
            public string ToolTip { get; set; }
    
            public string ImageName { get; set; }
    
            public int Status { get; set; }
            
            #endregion
    
            public TvAkten()
            {
                this.AkteMembers = new ObservableCollection<TvVorgang>();
            }
    
            public ObservableCollection<TvVorgang> AkteMembers { get; set; }
            
        }
    
    //ViewModel-Klasse für Akten
    public partial class TreeViewAktenViewModel : ViewModel<TvAkten>
        {
            public TreeViewAktenViewModel(TvAkten model)
                : base(model)
            {
            }
            #region Attribute-Properties
            private string _AkteName;
            public string AkteName
            {
                get
                {
                    return this._AkteName;
                }
                set
                {
                    if (this._AkteName != value)
                    {
                        this._AkteName = value;
                        this.OnPropertyChanged("AkteName");
                    }
                }
            }
            private string _ToolTip;
            public string ToolTip
            {
                get
                {
                    return this._ToolTip;
                }
                set
                {
                    if (this._ToolTip != value)
                    {
                        this._ToolTip = value;
                        this.OnPropertyChanged("ToolTip");
                    }
                }
            }
            private string _ImageName;
            public string ImageName
            {
                get
                {
                    return this._ImageName;
                }
                set
                {
                    if (this._ImageName != value)
                    {
                        this._ImageName = value;
                        this.OnPropertyChanged("ImageName");
                    }
                }
            }
            private int _Status;
            public int Status
            {
                get
                {
                    return this._Status;
                }
                set
                {
                    if (this._Status != value)
                    {
                        this._Status = value;
                        this.OnPropertyChanged("Status");
                    }
                }
            }
            #endregion
    
            #region Navigation-Properties
            /// <summary>
            /// Holt alle Akten, die Benutzers ausgewählt hat<see cref="VorgangViewModel"/>
            /// </summary>
            public TreeViewVorgangViewModel Akten2TreeView(List<int> AktenIDs)
            {
                return new TreeViewVorgangViewModel(AktenIDs);
            }
            #endregion
        }
    

    Gleiche Konstrukte habe ich für die beiden unteren Ebenen erstellt.

    und nun die UserControls:

    <!--hier das UserControl für den TreeView--> <UserControl x:Class="TestClass.TestTreeViewNeu" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:TestClass.Model;assembly=TestClass.Model" xmlns:converters="clr-namespace:TestClass.View.WPF" mc:Ignorable="d" Loaded="TreeViewUserControlView_Loaded" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <!--Datacontext--> <CollectionViewSource x:Key="treeViewListViewSource" /> <!--Converter--> <converters:AkteIntToImageSourceConverter x:Key="akteIntToImageSourceConverter"/> <converters:VorgangIntToImageSourceConverter x:Key="vorgangIntToImageSourceConverter"/> <converters:ErgebnisStringToImageSourceConverter x:Key="ergebnisStringToImageSourceConverter"/> </UserControl.Resources> <Grid> <TreeView Name="trvAkten" ItemsSource="{Binding Source={StaticResource treeViewListViewSource}}" > <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type local:TvAkten}" ItemsSource="{Binding AkteMembers}"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Status, Converter={StaticResource akteIntToImageSourceConverter}}" /> <TextBlock Text="{Binding AkteName}"/> </StackPanel> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="{x:Type local:TvVorgang}" ItemsSource="{Binding VorgangMembers}"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Status, Converter={StaticResource vorgangIntToImageSourceConverter}}" /> <TextBlock Text="{Binding VorgangName}"/> </StackPanel> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type local:TvErgebnis}"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding ErgebnisName, Converter={StaticResource ergebnisStringToImageSourceConverter}}" /> <TextBlock Text="{Binding ErgebnisName}"/> </StackPanel> </DataTemplate> </TreeView.Resources> </TreeView> </Grid> </UserControl> <!--hier die Collections für die Auswahl-->
    <!--UserControl der StartSeite--> <UserControl x:Class="VerDaNAS.View.WPF.StartSeiteGUI" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestClass.View.WPF" xmlns:Fluent="clr-namespace:Fluent;assembly=Fluent" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:converters="clr-namespace:TestClss.View.WPF" xmlns:command="clr-namespace:TestClass.View.WPF" xmlns:viewModel="clr-namespace:TestClass.ViewModel;assembly=TestClass.ViewModel" mc:Ignorable="d" x:Name="StartUsercontrolView" Loaded="StartUserControlView_Loaded" Opacity="1"> <UserControl.Resources> <!--Datacontext--> <CollectionViewSource x:Key="akteViewModelListViewSource" /> <CollectionViewSource x:Key="vorgaengeCollectionViewSource" /> ... </UserControl.Resources> <!--Listenbereich--> ... <Grid Name="StartSeiteGridDataGrids"> ... <DataGrid Name="StartSeiteAktenDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource akteViewModelListViewSource}}" SelectedValuePath="AkteID" SelectionChanged="aktenDataGrid_SelectionChanged" Style="{DynamicResource DataGridStyleAkte}" RowDetailsVisibilityMode="{Binding Path=IsChecked, ElementName=akteDetailsCheckBox, Converter={StaticResource ChangeDetailsVisibleConverter}}" RowDetailsTemplate="{DynamicResource AkteDatagridDetails}" IsReadOnly="True" > ... </DataGrid> ... <DataGrid Name="StartSeiteVorgaengeDataGrid" AutoGenerateColumns="False" SelectedValuePath="VorgangID" Style="{DynamicResource DataGridStyleVorgang}" ItemsSource="{Binding Source={StaticResource vorgaengeCollectionViewSource}}" RowDetailsVisibilityMode="{Binding Path=IsChecked, ElementName=vorgangDetailsCheckBox, Converter={StaticResource ChangeDetailsVisibleConverter}}" RowDetailsTemplate="{StaticResource VorgangDatagridDetails}" IsReadOnly="True"> ... </DataGrid> ... </Grid> ... </UserControl>

    Im CodeBehind werden in der Loaded-Methode die Instanzen für die Collections zugewiesen:

    //CodeBehind für das StartSeite-UserControl
    ...
    private void StartUserControlView_Loaded(object sender, RoutedEventArgs e)
            {
                vorgaengeViewSource = this.FindResource("vorgaengeCollectionViewSource") as CollectionViewSource;
                aktenViewSource = this.FindResource("akteViewModelListViewSource") as CollectionViewSource;
    
                aktenViewSource.Source = BenutzerAngemeldetViewModel.Instance.AktenBenutzer;
            }
    
    //CodeBehind für das TreeView-UserControl
    private void TreeViewUserControlView_Loaded(object sender, RoutedEventArgs e)
            {
                treeViewViewSource = this.FindResource("treeViewListViewSource") as CollectionViewSource;
                trvAkten.DataContext = TreeViewAktenViewModel.Instance;
            }

    Wo und wie sollte dann - deiner Meinung nach - das CurrentChanged Ereignis auswertet werden???

    Ich dachte, ich könnte die Collections für den TreeView dann laden, wenn das UserControl verlassen wird. Dies geschieht über einen Button in dem UserControl der Startseite, der einen Command aufruft, mit dem dann das neue UseControl geladen wird.

    Gruß Jürgen

    Freitag, 29. Januar 2016 07:49
  • Hi Jürgen,
    ich habe Deine Beiträge mehrmals gelesen. Ich habe aber nicht verstanden, wie Dein Datenmodell aussieht. Du hast 3 separate Listen "Akten", "Vorgänge" und "Ergebnisse". Unklar ist, wie diese Listen in Beziehung stehen. Auch ist nicht ersichtlich, wie die Quelle für treeViewListViewSource aussieht. Wenn Du wirklich die Inhalte der 3 Listen in einem TreeView darstellen willst, dann musst Du entsprechende Listen in die Objekte einbetten und auch füllen, so dass die entsprechzenden Bezüge entstehen.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Donnerstag, 4. Februar 2016 19:00
  • Hallo Peter,

    vielen Dank für deine Überlegungen.

    Das Datenmodell ist ziemlich umfangreich und die Tabellen bestehen in bestimmten Beziehungen.

    Ich habe es jetzt aber über ein ViewModel für den TreeView hingekriegt.

    Gruß Jürgen

    • Als Antwort markiert Jürgen Sch Freitag, 5. Februar 2016 07:32
    Freitag, 5. Februar 2016 07:32