wpf MVVM 中带有 Treeview 的 HierarchicalDataTemplate

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12165754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 05:08:12  来源:igfitidea点击:

HierarchicalDataTemplate with Treeview in MVVM

wpfxamlbindingtreeviewhierarchicaldatatemplate

提问by DeeDub84

I'm relatively new to MVVM and WPF. I'm attempting to fill a TreeView control with a directory and it's files / subdirectories (in effect the contents of a zip file that I have unpacked)

我对 MVVM 和 WPF 比较陌生。我试图用一个目录和它的文件/子目录填充 TreeView 控件(实际上是我解压的 zip 文件的内容)

Following along after this SO question, I have the following class:

在这个 SO question 之后,我有以下课程:

namespace IFR_Full.Model
{
    public class Item
    {
        public string Name { get; set; }
        public string Path { get; set; }
    }

    public class FileItem : Item
    {
    }

    public class DirectoryItem : Item
    {
        public List<Item> Items { get; set; }

        public DirectoryItem()
        {
            Items = new List<Item>();
        }
    }

    public class TVItemProvider
    {
        public List<Item> GetItems(string path)
        {
            var items = new List<Item>();
            var dirInfo = new DirectoryInfo(path);

            foreach (var directory in dirInfo.GetDirectories())
            {
                var item = new DirectoryItem
                    {
                        Name = directory.Name,
                        Path = directory.FullName,
                        Items = GetItems(directory.FullName)
                    };
                items.Add(item);
            }

            foreach (var file in dirInfo.GetFiles())
            {
                var item = new FileItem
                {
                    Name = file.Name,
                    Path = file.FullName
                };
                items.Add(item);
            }
            return items;
        }
    }
}

In my ViewModel class I have these properties:

在我的 ViewModel 类中,我有这些属性:

TVItemProvider TVIP = new TVItemProvider();

private List<Item> _tvitems;
public List<Item> TVItems
{
    get { return _tvitems; }
}

which is created in this method:

这是在此方法中创建的:

private void LoadIDMLTreeView(string path)
{
    _tvitems = TVIP.GetItems(path);
}

I set the header and DataContext of my MainWindow like this:

我像这样设置 MainWindow 的标题和 DataContext:

...
xmlns:ViewModel="clr-namespace:IFR_Full"
xmlns:Model ="clr-namespace:IFR_Full.Model"
...

<Window.DataContext>
    <ViewModel:ExcelImportViewModel/>
</Window.DataContext>

and set my treeview xaml code like this:

并像这样设置我的 treeview xaml 代码:

<TreeView ItemsSource="{Binding}" Name="IDMLView" Margin="10,171.74,10,8" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type Model:DirectoryItem}" ItemsSource="{Binding Path=TVItems}">
            <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" />                  
        </HierarchicalDataTemplate> 
        <DataTemplate DataType="{x:Type Model:FileItem}">
     <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" />
    </DataTemplate>             
 </TreeView.Resources>
</TreeView>

When I run the program in debug mode I can see that TVItems contains the appropriate items (Directories and files), but my TreeView control is blank.

当我在调试模式下运行程序时,我可以看到 TVItems 包含适当的项目(目录和文件),但我的 TreeView 控件是空白的。

I imagine that the issue is with the bindings?

我想问题出在绑定上?

采纳答案by HichemSeeSharp

  • Change <TreeView ItemsSource="{Binding}" ...to <TreeView ItemsSource="{Binding TVItems}" ...
  • Also , Change to <HierarchicalDataTemplate DataType="{x:Type local:DirectoryItem}" ItemsSource="{Binding Items}" >
  • Your class has to be like this :

     public class TVItemProvider
        {
    
            List<object> items = new List<object>();
              DirectoryInfo dirInfo;
              public List<object> GetItems(string path)
            {
                dirInfo = new DirectoryInfo(path);
                foreach (var directory in dirInfo.GetDirectories())
                {
                    var item = new DirectoryItem
                    {
                        Name = directory.Name,
                        Path = directory.FullName,
                        Items = new TVItemProvider().GetItems(directory.FullName)
                    };
                    items.Add(item);
                }
    
                foreach (var file in dirInfo.GetFiles())
                {
                    var item = new FileItem
                    {
                        Name = file.Name,
                        Path = file.FullName
                    };
    
                    items.Add(item);
                }
                return items;
            }
    

    }

  • Finally change the type of your lists to List<object>(all of them)
    Hope it would help

  • 更改<TreeView ItemsSource="{Binding}" ...<TreeView ItemsSource="{Binding TVItems}" ...
  • 另外,更改为 <HierarchicalDataTemplate DataType="{x:Type local:DirectoryItem}" ItemsSource="{Binding Items}" >
  • 你的班级必须是这样的:

     public class TVItemProvider
        {
    
            List<object> items = new List<object>();
              DirectoryInfo dirInfo;
              public List<object> GetItems(string path)
            {
                dirInfo = new DirectoryInfo(path);
                foreach (var directory in dirInfo.GetDirectories())
                {
                    var item = new DirectoryItem
                    {
                        Name = directory.Name,
                        Path = directory.FullName,
                        Items = new TVItemProvider().GetItems(directory.FullName)
                    };
                    items.Add(item);
                }
    
                foreach (var file in dirInfo.GetFiles())
                {
                    var item = new FileItem
                    {
                        Name = file.Name,
                        Path = file.FullName
                    };
    
                    items.Add(item);
                }
                return items;
            }
    

    }

  • 最后将您的列表类型更改为List<object>(所有)
    希望它会有所帮助