这里只对最近使用到的分层树做一些记录,有复选框示例,支持父级选中状态改变子集同步变化

废话不多说,直接上源码

View布局

                <TreeDataGrid
Height="710"
BorderBrush="Gray"
CanUserResizeColumns="False"
FontSize="16"
Source="{Binding TreeDataGridSource}">
<TreeDataGrid.Resources>
<DataTemplate x:Key="CheckBoxCellTemplate" x:DataType="vm:TreeDataModel">
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" />
</DataTemplate>
</TreeDataGrid.Resources>
</TreeDataGrid>

model对象

    public class TreeDataModel : INotifyPropertyChanged
{
private string _name; public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged(nameof(Name));
}
} private int? _age; public int? Age
{
get { return _age; }
set
{
_age = value;
OnPropertyChanged(nameof(Age));
}
} public bool _isSelected; public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
OnPropertyChanged(nameof(IsSelected)); // 如果是分类节点,更新所有子项的状态
if (IsCategory)
{
foreach (var child in Children)
{
child.IsSelected = value;
}
}
}
} private string _department; public string Department
{
get => _department;
set
{
if (_department != value)
{
_department = value;
OnPropertyChanged(nameof(Department));
}
}
} private string _category; public bool IsCategory => !string.IsNullOrEmpty(Category); public bool IsExpanded { get; set; } = true; public string Category
{
get { return _category; }
set
{
_category = value;
OnPropertyChanged(nameof(Category));
}
} private ObservableCollection<TreeDataModel> _children = new ObservableCollection<TreeDataModel>(); public ObservableCollection<TreeDataModel> Children
{
get { return _children; }
set
{
_children = value;
OnPropertyChanged(nameof(Children));
}
} public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}

vm 数据刷新逻辑

    private HierarchicalTreeDataGridSource<TreeDataModel> _treeDataGridSource =
new HierarchicalTreeDataGridSource<TreeDataModel>(new List<TreeDataModel>()); public HierarchicalTreeDataGridSource<TreeDataModel> TreeDataGridSource
{
get { return _treeDataGridSource; }
set
{
_treeDataGridSource = value;
OnPropertyChanged(nameof(TreeDataGridSource));
}
} private TreeDataModel selectedItem; public TreeDataModel SelectedItem
{
get => selectedItem;
set
{
selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
}
} public async void InitTreeData()
{
List<TreeDataModel> data = new List<TreeDataModel>();
for (int i = 0; i < 10; i++)
{
int value = 10 + i;
data.Add(new TreeDataModel()
{
Age = value,
Name = $"示例{value}",
Department = "测试部",
});
} for (int i = 0; i < 7; i++)
{
int value = 10 + i;
data.Add(new TreeDataModel()
{
Age = value,
Name = $"张三{value}",
Department = "研发",
});
} for (int i = 23; i < 50; i++)
{
int value = 10 + i;
data.Add(new TreeDataModel()
{
Age = value,
Name = $"酒香也怕巷子深{value}",
Department = "心如止水",
});
} //聚合形成树形数据集
var categoryGroups = data
.GroupBy(i =>
{
// 按照"-"前面的部分分类
var dashIndex = i.Department.IndexOf('-');
return dashIndex > 0 ? i.Department.Substring(0, dashIndex) : i.Department;
});
List<TreeDataModel> listData = new List<TreeDataModel>();
foreach (var group in categoryGroups)
{
var category = new TreeDataModel { Category = group.Key }; foreach (var item in group)
{
category.Children.Add(item);
} listData.Add(category);
} TreeDataGridSource =
new HierarchicalTreeDataGridSource<TreeDataModel>(listData)
{
Columns =
{
new HierarchicalExpanderColumn<TreeDataModel>(
new TextColumn<TreeDataModel, string>(
"人员",
x => x.IsCategory ? $"{x.Category}({x.Children.Count}成员)" : x.Name,
GridLength.Auto)
,
x => x.Children,
isExpandedSelector: x => x.IsExpanded),
new TextColumn<TreeDataModel, int?>(
"年龄",
x => x.Age,
GridLength.Auto),
new TemplateColumn<TreeDataModel>(
"",
"CheckBoxCellTemplate", // 使用自定义模板
width: GridLength.Auto),
},
}; TreeDataGridSource.RowSelection.SelectionChanged += (s, e) =>
{
if (s is TreeDataGridRowSelectionModel<TreeDataModel> selec)
{
if (selec.SelectedItem is TreeDataModel selectModel)
{
SelectedItem = selectModel;
}
}
};
}

关键点,

1.数据格式绑定基本都在vm完成treedatagrid数据源集合需要绑定HierarchicalTreeDataGridSource,而不是传统的ObservableCollection

2.行选中时间SelectionChanged,控件不支持直接使用SelectionChanged,需要vm业务层订阅RowSelection来引出SelectionChanged,数据集每次变化都需要重新订阅

3.复选框:

数据集Columns绑定时其实有CheckBoxColumn列,不过这里演示通过绑定资源键的形式 x:Key="CheckBoxCellTemplate"实现复选框

父级状态改变影响子集,Avalonia原本的TreeDataGrid并没有对这个实现,但是自己可以通过通过对IsSelected属性变化时,验证IsCategory是否是分类节点 从而更改子集选中状态

Avalonia treedatagrid使用杂记的更多相关文章

  1. [Erlang 0118] Erlang 杂记 V

       我在知乎回答问题不多,这个问题: "对你职业生涯帮助最大的习惯是什么?它是如何帮助你的?",我还是主动回答了一下.    做笔记 一开始笔记软件做的不好的时候就发邮件给自己, ...

  2. Ubuntu杂记——Ubuntu下用虚拟机共享上网

    由于最近把自己电脑环境换成了Ubuntu,但学校的网络是电信的闪讯,大学里用过的人都知道这货有多坑,而且没有Linux客户端,上网都是问题,怪不得国内用Linux的人那么少,特别是高校的学生(让我瞎逼 ...

  3. 一个ubuntu phper的自我修养(杂记)

    ubuntu使用杂记 1.flatabulous安装使用. flatabulous是一个ubuntu图标主题. 使用它,必须得安装tweak插件. sudo add-apt-repository pp ...

  4. 有关Java的日期处理的一些杂记

    在企业应用开发中,经常会遇到日期的相关处理,说实话JDK自带的日期方法很难用.就我个人而言我一般都会采用joda-time来替代JDK自身的日期. 这篇文章是杂记,所以写的比较零散,希望大家不要见怪. ...

  5. 分布式系统之CAP理论杂记[转]

    分布式系统之CAP理论杂记 http://www.cnblogs.com/highriver/archive/2011/09/15/2176833.html 分布式系统的CAP理论: 理论首先把分布式 ...

  6. Redis杂记

    参考资料: Redis 教程 | 菜鸟教程 : http://www.runoob.com/redis/redis-tutorial.html Redis快速入门 :http://www.yiibai ...

  7. MySQL杂记

    参考资料: w3school  SQL 教程 : http://www.w3school.com.cn/sql/index.asp 21分钟 MySQL 入门教程 : http://www.cnblo ...

  8. Android之开发杂记(一)

    1.cygwin环境变量设置 可在Cygwin.bat 中设置 set NDK_ROOT=P:/android/android-ndk-r8e 或者在home\Administrator\.bash_ ...

  9. ios程序开发杂记

    ios程序开发杂记 一.程序构建 与一般的程序构建无太大区别,都是源文件编译链接这一套,通常是在mac上做交叉编译,也就是利用xcode里带的ios编译工具集去生成arm架构的ios程序(或是x86的 ...

  10. .NET Core UI框架Avalonia

    .NET Core UI框架Avalonia,Avalonia是一个基于WPF XAML的跨平台UI框架,并支持多种操作系统:Windows(.NET Framework,.NET Core),Lin ...

随机推荐

  1. 0x01 - 我的第一个 Object Visitor

    我的第一个 Object Visitor 预演准备 为了顺利的进行测试,你需要确保本地已经安装了以下这些必备的软件: dotnet 2.1 或者以上版本的 SDK,我们更建议直接安装 dotnet 5 ...

  2. 解决更新WIFI驱动后出现网络适配器黄色三角警告

    更新WIFI驱动后出现网络适配器黄色三角警告问题的解决方案 在更新 Intel 无线网卡驱动后,遇到了网络适配器异常的问题,尤其是在曾经安装/卸载过 VMware 的电脑上.本篇文章将详细介绍这个问题 ...

  3. excel/wps, 转code128字体宏, 部分字符串出现空格, 导致条码断裂无法扫描的解决方案

    原宏是网上抄的, 传播比较广的那个. 后来发现, 部分条码出现空格断裂, 导致PDA无法扫描, 经搜索在一个帖子里, 发现是因为: 宏计算条码时, 会出现校验位刚好是空格的情况, 而空格在code12 ...

  4. MySQL中以数值类型存储IP地址

    前言   数据库中存储IP地址的时候,推荐使用整数存储而不是字符串.一般来说, 在保证正确性的前提下,尽量使用最小的数据类型来存储和展示数据:小的数据类型一般比大的更快,因为小的数据类型占用的磁盘空间 ...

  5. 使用Vditor将Markdown文档渲染成网页(Vite+JS+Vditor)

    1. 引言 编写Markdown文档现在可以说是程序员的必备技能了,因为Markdown很好地实现了内容与排版分离,可以让程序员更专注于内容的创作.现在很多技术文档,博客发布甚至AI文字输出的内容都是 ...

  6. Windows基线检查

    Windows 脆弱性检查是指通过一系列工具和方法,评估 Windows 操作系统中的潜在安全漏洞,以发现并修复可能被攻击者利用的弱点.这个过程包括对系统的安全配置.补丁更新.权限设置以及其他安全因素 ...

  7. Mac os的防火墙导致开的热点手机连不上

    在工位上用Mac给手机开热点用,结果今天手机一直连不上Mac开的热点,最后把Mac的防火墙关了就能让手机连上了,连上了再把防火墙打开也不影响连接.

  8. ChunJun 1.16 Release版本即将发布,bug 捉虫活动邀您参与!

    亲爱的社区小伙伴们,历时数月,我们很高兴地宣布,ChunJun 即将迎来 1.16 Release 版本的正式发布.在新版本中,ChunJun 新增了一批常用功能,进行了多项功能优化和问题修复,并在用 ...

  9. About me and the blog

    About me and the blog About me 坐标\(CQ\),可以叫我\(Luoyu\)/洛雨/呆猫(似乎混入了奇怪的东西,时常模仿呆猫说话故而得名)/猫老大(???不知道啥时候下一 ...

  10. 禁止Apache显示文件列表

    通过.htaccess文件 可以在根目录新建或修改 .htaccess 文件中添加 .代码如下: <Files *> Options -Indexes</Files> 就可以禁 ...