RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1254880
Accepted
Денис
Денис
Asked:2022-03-12 18:10:31 +0000 UTC2022-03-12 18:10:31 +0000 UTC 2022-03-12 18:10:31 +0000 UTC

在 TreeView WPF 中创建层次结构和显示

  • 772

有一个描述产品的类:

using System.Collections.ObjectModel;

namespace Test
{
    public class Product
    {
        public ObservableCollection<Product> productName { get; set; }

        public string nameOfProduct { get; set; }

        public Product()
        {
            productName = new ObservableCollection<Product>();
        }
    }
}

此代码有一个链接:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TreeView Name="TrvView">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:Product}" ItemsSource="{Binding productName}">
                    <TextBlock Text="{Binding nameOfProduct}" />
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

有一段代码以分层形式创建和显示集合的元素:

 private void Create()
    {
        for (int i = 0; i < 10; i++)
        {
            bread = new Product(){nameOfProduct = "Хлеб"};
            for (int j = 0; j < 10; j++)
            {
                breadVarieties = new Product(){nameOfProduct = "Сорт хлеба " + j.ToString()};
                bread.productName.Add(breadVarieties);
            }
            TrvView.Items.Add(bread);
        }
    }

结果,我得到了预期的漂亮结果:

在此处输入图像描述

我想不到的是:我如何以这样的方式实现代码,例如,在每 10 级面包之后,不创建位于上方的下一个根元素,我将数据放在下面。大概是这样的:

在此处输入图像描述

如果我自己预先确定嵌套深度(再写几个 for 循环并添加元素),它对我有用。如何以编程方式执行此操作?

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    aepot
    2022-03-12T19:03:43Z2022-03-12T19:03:43Z

    WPF 不直接使用控件,而是使用数据绑定。有一种 MVVM 设计模式可以帮助以正确的方式组织 WPF 应用程序,但让我们从简单的开始。

    分配DataContext和实施INotifyPropertyChanged

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private ObservableCollection<Product> _products;
    
        public ObservableCollection<Product> Products
        {
            get => _products;
            set
            {
                _products = value;
                OnPropertyChanged();
            } 
        }
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // здесь будем писать код
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    

    对于数据模型,我们还实现了 INPC。

    我已将属性重命名为更清晰且与常见的 C# 命名约定更一致。

    public class Product : INotifyPropertyChanged
    {
        private string _name;
        private ObservableCollection<Product> _items = new ObservableCollection<Product>();
    
        public ObservableCollection<Product> Items
        {
            get => _items;
            set
            {
                _items = value;
                OnPropertyChanged();
            } 
        }
    
        public string Name;
        {
            get => _name;
            set
            {
                _name = value;
                OnPropertyChanged();
            } 
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    

    这是 XAML

    <Window x:Class="Test.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Test"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
        <Grid>
            <TreeView ItemsSource="{Binding Products}">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type local:Product}" ItemsSource="{Binding Items}">
                        <TextBlock Text="{Binding Name}" />
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </Grid>
    </Window>
    

    项目结构已准备就绪。现在,无论您如何更改集合的内容,无论您如何重命名元素,TreeView它都会自动监控树中的所有更改并立即将它们显示在界面中。

    请注意,该TreeView名称不再存在且不再需要。

    现在让我们填充树

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Products = new ObservableCollection<Product>();
        FillProducts(Products, 10, 2, true);
    }
    
    private void FillProducts(ObservableCollection<Product> items, int count, int depth, bool isRoot)
    {
        for (int i = 0; i < count; i++)
        {
            Product product = new Product() { Name = $"{isRoot ? "Хлеб" : "Сорт хлеба"} {i + 1}" };
            items.Add(product);
            if (i == count - 1 && depth > 1)
                FillProducts(product.Items, count, depth - 1, false);
        }
    }
    

    准备好。


    PS您还可以出于娱乐目的直观地查看此代码的工作方式。为此,让我们添加一点异步和暂停。

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Products = new ObservableCollection<Product>();
        await FillProductsAsync(Products, 10, 2, true);
    }
    
    private async Task FillProductsAsync(ObservableCollection<Product> items, int count, int depth, bool isRoot)
    {
        for (int i = 0; i < count; i++)
        {
            Product product = new Product() { Name = $"{isRoot ? "Хлеб" : "Сорт хлеба"} {i + 1}" };
            items.Add(product);
            await Task.Delay(500);
            if (i == count - 1 && depth > 1)
                FillProducts(product.Items, count, depth - 1, false);
        }
    }
    

    现在您可以直观地看到元素是如何一一添加到树中的。

    • 1

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5