You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# WPF层级TreeView中添加作物年份额外层级?

在WPF TreeView中添加年份层级的实现方案

我来帮你搞定这个TreeView加年份层级的需求,其实核心是数据分组+模板适配,一步步来:

1. 新增中间层级的数据模型

首先我们需要一个承载年份和对应Crop集合的中间节点类,用来作为Field和Crop之间的层级:

public class YearNode
{
    // 年份值(如果有未指定年份的情况,可以加DisplayName属性优化显示)
    public int Year { get; set; }
    // 该年份对应的所有Crop
    public IEnumerable<Crop> Items { get; set; }
    // 可选:处理未指定年份的友好显示
    public string DisplayName => Year == 0 ? "未指定年份" : Year.ToString();
}

2. 给Field类添加分组后的年份集合属性

接下来要把Field原有的Crop集合按年份分组,生成YearNode的集合。如果你用的是MVVM,也可以在ViewModel里处理这个逻辑:

public class Field
{
    // 原有属性,比如FieldName、原Crop集合Items
    public string FieldName { get; set; }
    public IEnumerable<Crop> Items { get; set; }

    // 新增:按CropYear分组后的年份节点集合
    public IEnumerable<YearNode> YearGroups
    {
        get
        {
            if (Items == null) return Enumerable.Empty<YearNode>();
            
            // 分组逻辑:处理可能的null年份,按年份排序
            return Items
                .GroupBy(crop => crop.CropYear.HasValue ? crop.CropYear.Value.Year : 0)
                .OrderBy(group => group.Key)
                .Select(group => new YearNode
                {
                    Year = group.Key,
                    Items = group.OrderBy(crop => crop.CropName) // 可选:给Crop加个排序
                });
        }
    }
}

注意:如果你的Crop集合是动态变化的(比如增删Crop),记得让Field实现INotifyPropertyChanged,在Items变化时触发YearGroups的属性变更通知,或者把YearGroups改成ObservableCollection<YearNode>并在Items更新时重新生成集合。

3. 修改TreeView的XAML模板

现在要更新TreeView的资源,新增YearNode的模板,同时把Field的ItemsSource从原Crop集合改成YearGroups:

<TreeView x:Name="tvFields" Margin="10" HorizontalContentAlignment="Stretch">
    <TreeView.Resources>
        <!-- 年份节点模板:显示年份+该年份的Crop数量 -->
        <HierarchicalDataTemplate DataType="{x:Type local:YearNode}" ItemsSource="{Binding Items}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding DisplayName}" FontWeight="Bold" Margin="0 0 5 0"/>
                <TextBlock Text="($" Foreground="Gray"/>
                <TextBlock Text="{Binding Items.Count()}" Foreground="Gray"/>
                <TextBlock Text=")" Foreground="Gray"/>
            </StackPanel>
        </HierarchicalDataTemplate>

        <!-- Field节点模板:修改ItemsSource为YearGroups -->
        <HierarchicalDataTemplate DataType="{x:Type entites:Field}" ItemsSource="{Binding YearGroups}">
            <StackPanel Orientation="Horizontal" Background="LightBlue">
                <TextBlock Text="{Binding FieldName}" Margin="5"/>
                <!-- 保留你原来Field的其他UI元素 -->
            </StackPanel>
        </HierarchicalDataTemplate>

        <!-- 原有Crop模板保持不变,它的子项还是Fertilizer、Pesticide等 -->
        <HierarchicalDataTemplate DataType="{x:Type entites:Crop}" ItemsSource="{Binding Items}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding CropName}" Margin="5"/>
                <TextBlock Text="(" Foreground="Gray"/>
                <TextBlock Text="{Binding CropYear, StringFormat='yyyy'}" Foreground="Gray"/>
                <TextBlock Text=")" Foreground="Gray"/>
            </StackPanel>
        </HierarchicalDataTemplate>

        <!-- 保留你原来的Fertilizer、Pesticide等模板 -->
        <DataTemplate DataType="{x:Type entites:Fertilizer}">
            <TextBlock Text="{Binding FertilizerName}" Margin="10 0"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type entites:Pesticide}">
            <TextBlock Text="{Binding PesticideName}" Margin="10 0"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

4. 最终效果

这样你的TreeView结构就变成了:

  • Field
    • 2017 (3)
      • Crop A (2017)
        • Fertilizer X
        • Pesticide Y
      • Crop B (2017)
        • ...
    • 2018 (2)
      • Crop C (2018)
        • ...
    • 未指定年份 (1)
      • Crop D
        • ...

内容的提问来源于stack exchange,提问作者Lyror

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:11:01