none
DataBinding an TreeView RRS feed

  • Frage

  • Ich möchte gern eine spezielle Klasse in einer TreeView anzeigen.

    Meine TreeView:

                        <TreeView Name="treeViewBrowserFavorits" Margin="0,0,-4,-5" 
                                       Width="Auto" Height="Auto"
                                       ItemsSource="{Binding}" >
                        </TreeView>

    Meine Klasse für die Daten:

        public class MyItem
        {
            public string Name { get; set; }
    
            public IList<MyItem> Items { get; set; }
        }

    Meine kleiner Beispiel-Befüllungscode:

                List<MyItem> items = new List<BrowserFavoritsItem>();
                items.Add(new MyItem() { Name = "Name1" });
                items.Add(new MyItem() { Name = "Name2" });
    
                List<BrowserFavoritsItem> x = new List<MyItem>();
                x.Add(new MyItem() { Name = "UnterItem1" });
                items.Add(new MyItem() { Name = "Name3", Items = x});
    
                items.Add(new MyItem() { Name = "Name4" });
                treeViewBrowserFavorits.DataContext = items;


    Es zeigt aber immer nur 4 Zeilen "MeinProgramm.MyItem" an. Was mache ich falsch?


    Koopakiller - http://koopakiller.ko.ohost.de/

    Montag, 13. Februar 2012 17:34
    Moderator

Antworten

  • Hallo,

    Du brauchst noch ein HierarchicalDataTemplate.

    Schau Dir mal an: Displaying Hierarchical Data with the WPF Tree View control

    Gruß Elmar

    Montag, 13. Februar 2012 19:15
  • Hier mal eine kleine Demo:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525"
            xmlns:b="clr-namespace:WpfApplication1">
      <Window.Resources>
        <b:ViewModel x:Key="vm"/>
      </Window.Resources>
      <Grid DataContext="{Binding Source={StaticResource vm}}">
        <TreeView Name="treeViewBrowserFavorits" ItemsSource="{Binding BrowserFavorits}" >
          <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding BrowserFavorits}"
                                                          DataType="{x:Type b:BrowserFavoritsItem}">
              <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
          </TreeView.ItemTemplate>
        </TreeView>
      </Grid>
    </Window>
    

    Dazu der Code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication1
    {
      /// <summary>
      /// Interaction logic for MainWindow.xaml
      /// </summary>
      public partial class MainWindow : Window
      {
        public MainWindow()
        {
          InitializeComponent();
        }
      }
    
      public class ViewModel
      {
        public ViewModel()
        {
          this.BrowserFavorits = new List<BrowserFavoritsItem>();
    
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 1", null));
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 2", null));
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 3", null));
    
          List<BrowserFavoritsItem> x = new List<BrowserFavoritsItem>();
          x.Add(new BrowserFavoritsItem("Unteritem 1", null));
    
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 4", x));
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 5", null));
        }
        public List<BrowserFavoritsItem> BrowserFavorits { get; set; }
      }
    
      public class BrowserFavoritsItem
      {
        public BrowserFavoritsItem(string name, IList<BrowserFavoritsItem> subitems)
        {
          this.Name = name;
          this.BrowserFavorits = subitems;
        }
        public string Name { get; set; }
        public IList<BrowserFavoritsItem> BrowserFavorits { get; set; }
      }
    }
    

    --
    Viele Gruesse
    Peter

    Dienstag, 14. Februar 2012 18:54

Alle Antworten

  • Hallo,

    Du brauchst noch ein HierarchicalDataTemplate.

    Schau Dir mal an: Displaying Hierarchical Data with the WPF Tree View control

    Gruß Elmar

    Montag, 13. Februar 2012 19:15
  • Danke erstmal für die Antwort. Ich habe jetzt den XAML-Code folgendermaßen erweitert:
                        <TreeView Name="treeViewBrowserFavorits" Margin="0,0,-4,-5" 
                          Width="Auto" Height="Auto"
                          ItemsSource="{Binding BrowserFavorits}" >
                            <TreeView.ItemTemplate>
                                <HierarchicalDataTemplate ItemsSource="{Binding BrowserFavorits}"
                                                          DataType="{x:Type b:BrowserFavoritsItem}">
                                    <TextBlock Text="{Binding Name}" />
                                </HierarchicalDataTemplate>
                            </TreeView.ItemTemplate>
                        </TreeView>

    Ansonsten wüsste ich nicht was ich noch ändern soll Damit es funktioniert. Hier nochmal der andere Code, da ich einies umbennenen musste:
            List<BrowserFavoritsItem> _browserFavorits = new List<BrowserFavoritsItem>();
            List<BrowserFavoritsItem> BrowserFavorits
            {
                get
                {
                    return _browserFavorits;
                }
                set
                {
                    _browserFavorits = value;
                } 
            }
    
            private void InsertItems()
            {
                string fileLocation = "";
    
                this.Dispatcher
                    .Invoke(new Action<System.String>(
                    logFileLocation => fileLocation = logFileLocation),
                    this.logFileLocation);
    
                ItemCollection tmp = dat.GetBrowserFavorits();
    
                BrowserFavorits.Add(new BrowserFavoritsItem("Item 1", null));
                BrowserFavorits.Add(new BrowserFavoritsItem("Item 2", null));
                BrowserFavorits.Add(new BrowserFavoritsItem("Item 3", null));
    
                List<BrowserFavoritsItem> x = new List<BrowserFavoritsItem>();
                x.Add(new BrowserFavoritsItem("Unteritem 1", null));
    
                BrowserFavorits.Add(new BrowserFavoritsItem("Item 4", x));
                BrowserFavorits.Add(new BrowserFavoritsItem("Item 5", null));
    }


    Koopakiller - http://koopakiller.ko.ohost.de/

    Dienstag, 14. Februar 2012 16:41
    Moderator
  • Hier mal eine kleine Demo:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525"
            xmlns:b="clr-namespace:WpfApplication1">
      <Window.Resources>
        <b:ViewModel x:Key="vm"/>
      </Window.Resources>
      <Grid DataContext="{Binding Source={StaticResource vm}}">
        <TreeView Name="treeViewBrowserFavorits" ItemsSource="{Binding BrowserFavorits}" >
          <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding BrowserFavorits}"
                                                          DataType="{x:Type b:BrowserFavoritsItem}">
              <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
          </TreeView.ItemTemplate>
        </TreeView>
      </Grid>
    </Window>
    

    Dazu der Code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication1
    {
      /// <summary>
      /// Interaction logic for MainWindow.xaml
      /// </summary>
      public partial class MainWindow : Window
      {
        public MainWindow()
        {
          InitializeComponent();
        }
      }
    
      public class ViewModel
      {
        public ViewModel()
        {
          this.BrowserFavorits = new List<BrowserFavoritsItem>();
    
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 1", null));
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 2", null));
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 3", null));
    
          List<BrowserFavoritsItem> x = new List<BrowserFavoritsItem>();
          x.Add(new BrowserFavoritsItem("Unteritem 1", null));
    
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 4", x));
          BrowserFavorits.Add(new BrowserFavoritsItem("Item 5", null));
        }
        public List<BrowserFavoritsItem> BrowserFavorits { get; set; }
      }
    
      public class BrowserFavoritsItem
      {
        public BrowserFavoritsItem(string name, IList<BrowserFavoritsItem> subitems)
        {
          this.Name = name;
          this.BrowserFavorits = subitems;
        }
        public string Name { get; set; }
        public IList<BrowserFavoritsItem> BrowserFavorits { get; set; }
      }
    }
    

    --
    Viele Gruesse
    Peter

    Dienstag, 14. Februar 2012 18:54
  • Das funktioniert schonmal, aber wie mache ich das dass ich zur laufzeit Itms hinzufüge, also mit einer variable von ViewModel?

    Ich weiß dabei leider nicht wie ich es von einer StaticResource zu einem Dynamischen umstellen kann.


    Koopakiller - http://koopakiller.ko.ohost.de/

    Mittwoch, 15. Februar 2012 15:04
    Moderator
  • Im Beispiel ist statisch nur der Verweis auf die Instanz des ViewModel. Wenn Du als Datenpuffer im ViewModel ein Objekt nimmst, was INotifiPropertyChanged implementiert, dann werden Änderungen in der Datenquelle auch an die Oberfläche (trotz statischem Verweis) gemeldet und führen zu einem “Refresh”. Eine ObservableCollection als Datenquelle erfüllt diese Bedingung.
     
    --
    Viele Gruesse
    Peter
    Mittwoch, 15. Februar 2012 18:10