V.CodeGenerator WPF代码生成器--自定义控件
前言
前言:
受 WTM 的影响,想自己尝试写一个自动生成WPF项目的代码生成器
本文主要用于介绍基础库中作者自定义的一些<自定义控件>的使用。
作者的功底还不是很成熟,请大家多多包涵。
前端控件主要使用了 HandyControl(点击可跳转控件文档) ,故此处仅提供一些额外的自定义控件使用。
一、引用Vampirewal.Core基础库
二、使用
基础库中的部分自定义控件已经在代码中进行了样式的引用,在窗体的Resources中,无需再进行引用,只需申明xmlns:vc=“Vampirewal.CustomControl”即可
也可以在Resources中添加引用
<ResourceDictionary Source="pack://application:,,,/Vampirewal.Core;component/WpfTheme/CoreTheme.xaml"/>
1、TitleContent
属性
属性名 | 介绍 |
---|---|
Title | 标题 |
TitleWidth | 标题宽度 |
TitleVerticalAlignment | 标题垂直对齐 |
TitlePadding | 控件内部填充 |
TitleForeground | 标题字体颜色 |
使用
<vc:TitleContent
Title="工程名称:"
TitleForeground="{StaticResource BaseForeground}"
TitleWidth="70">
<TextBox
Width="300"
Style="{StaticResource DefaultTextBox}"
Text="{Binding Entity.ProjectName}"
TextWrapping="Wrap" />
</vc:TitleContent>
2、SearchControl
属性
属性名 | 介绍 |
---|---|
SearchCommand | 搜索命令,用于绑定ICommand |
SearchTextStyle | 搜索文本框的样式,可自定义 |
SearchButtonStyle | 搜索按钮的样式,可自定义 |
使用
<vc:SearchControl Height="40" VerticalAlignment="Top" SearchCommand="{Binding SearchCommand}" />
3、LoadingContainer–带loading的容器控件
属性
属性名 | 介绍 |
---|---|
OnLoading | bool值,可通过ViewModel中绑定bool值控制启停 |
LoadingTips | Loading启用的时候,显示的文字 |
使用 |
<vc:LoadingContainer OnLoading="{Binding IsLoading}">
//这里放其他控件
</vc:LoadingContainer>
4、EditContainer–编辑页容器
属性
属性名 | 介绍 |
---|---|
CheckedColor | 选中颜色 |
LeftBackground | 左侧背景色. |
LeftForeground | 左侧前景色 |
MouseOverColor | 鼠标移过颜色 |
使用
<vc:EditContainer
CheckedColor="Orange"
LeftBackground="{StaticResource BaseBackground}"
LeftForeground="{StaticResource BaseBackground2}"
MouseOverColor="{StaticResource BaseBackground2}">
<vc:EditItem HeaderText="基本信息">
//此处仅能使用EditItem做内容容器
</vc:EditItem>
</vc:EditContainer>
实际样式
注意事项:EditItem是容器,高度是内部控件的高度和,控件的高度最好在编辑确定,避免动态的高度会导致实际使用中出现位移差
5、TreeListView
使用:类似于DataGrid的使用方式
<vc:TreeListView
Height="200"
VAttach:TouchEventCommands.Events="{Binding TreeListViewActionsCommand}"
Background="#FFE9E9E9"
ItemsSource="{Binding UserList2.BindingTreeItems}"
TreeBuilder="{Binding UserList2}"
>
<vc:TreeListView.FirstColumnInfo>
<vc:CustromFirstColumn
FirstColumnBindingPath="UserName"
FirstColumnHeader="姓名"
HasCheckBox="True" />
<!--<vc:AutoCodeFirstColumn />-->
</vc:TreeListView.FirstColumnInfo>
<vc:TreeListView.Columns>
<vc:TreeItemColumn Width="100" Header="登录名">
<vc:TreeItemColumn.CellTemplate>
<DataTemplate>
<TextBlock
Margin="0,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding TreeNode.LoginID}" />
</DataTemplate>
</vc:TreeItemColumn.CellTemplate>
</vc:TreeItemColumn>
<vc:TreeItemColumn Width="100" Header="性别">
<vc:TreeItemColumn.CellTemplate>
<DataTemplate>
<TextBlock
Margin="0,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding TreeNode.Gender}" />
</DataTemplate>
</vc:TreeItemColumn.CellTemplate>
</vc:TreeItemColumn>
<vc:TreeItemColumn Width="100" Header="密码">
<vc:TreeItemColumn.CellTemplate>
<DataTemplate>
<TextBlock
Margin="0,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding TreeNode.Passwod}" />
</DataTemplate>
</vc:TreeItemColumn.CellTemplate>
</vc:TreeItemColumn>
</vc:TreeListView.Columns>
<vc:TreeListView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}" />
</vc:TreeListView.ItemTemplate>
</vc:TreeListView>
大家可以看到有几个区别的地方:
1、TreeBuilder
2、FirstColumnInfo
依次给大家进行讲解
框架内封装了一个类,TreeBuilderByFullLoad,可根据数据源中的ParentId和ListId进行自动组合上下级,组成树形的类,需继承ITreeNode
public partial class Sys_User : ITreeNode
{
public string CurId { get; set; }//当前层级ID,无需和我的一样,自己按你自己的业务命名
public string ParentId { get; set; }//当前层级的父ID,一般都是取这个名字,也可以其他的,无所谓
//下面的方法鼠标移动上去查看,实际都是有中文注释的,我这懒得再标记一次了
public object GetCurrentNodeMark()
{
return CurId;
}
public object GetParentNodeMark()
{
return ParentId;
}
public bool IsParentNode(ITreeNode parentNode)
{
if (parentNode is Sys_User node)
return ParentId == node.CurId;
return false;
}
public bool IsSameNode(ITreeNode node)
{
if (node is Sys_User tmpNode)
return CurId == tmpNode.CurId;
return false;
}
public bool IsSameParent(ITreeNode node)
{
if (node is Sys_User tmpNode)
return ParentId == tmpNode.ParentId;
return false;
}
public bool IsSubNode(ITreeNode subNode)
{
if (subNode is Sys_User tmpNode)
return tmpNode.ParentId == CurId;
return false;
}
public void SetParentNodeMark(object parentObj)
{
ParentId = parentObj.ToString();
}
private bool _IsSelected;
private bool _IsExpanded;
/// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
DoNotify();
}
}
/// <summary>
/// 是否展开
/// </summary>
public bool IsExpanded
{
get { return _IsExpanded; }
set
{
_IsExpanded = value;
DoNotify();
}
}
}
有了实现ITreeNode的类之后,就可以写一个属性`public TreeBuilderByFullLoad<Sys_User> UserList2 { get; set; }
再准备好数据源,往里填数据
UserList2 = new TreeBuilderByFullLoad<Sys_User>();//实例化一个
List<Sys_User> cur = new List<Sys_User>();
Sys_User c1 = new Sys_User()
{
CurId=Guid.NewGuid().ToString(),
ParentId = Guid.Empty.ToString(),
UserName="c1",
LoginID="abc",
Gender=1,
Passwod = "yc"
};
cur.Add(c1);
Sys_User c2 = new Sys_User()
{
CurId = Guid.NewGuid().ToString(),
ParentId = c1.CurId,
UserName = "c2",
LoginID = "abc",
Gender = 1
};
cur.Add(c2);
Sys_User c3 = new Sys_User()
{
CurId = Guid.NewGuid().ToString(),
ParentId = c1.CurId,
UserName = "c3",
LoginID = "abc",
Gender = 1
};
cur.Add(c3);
Sys_User cc1 = new Sys_User()
{
CurId = Guid.NewGuid().ToString(),
ParentId = c2.CurId,
UserName = "cc1",
LoginID = "abc",
Gender = 1
};
cur.Add(cc1);
Sys_User cc2 = new Sys_User()
{
CurId = Guid.NewGuid().ToString(),
ParentId = c3.CurId,
UserName = "cc2",
LoginID = "abc",
Gender = 1,
Passwod="yc"
};
cur.Add(cc2);
Sys_User ccc1 = new Sys_User()
{
CurId = Guid.NewGuid().ToString(),
ParentId = cc2.CurId,
UserName = "ccc1",
LoginID = "abc",
Gender = 1,
Passwod = "yc"
};
cur.Add(ccc1);
UserList2.LoadFullNodes(cur);//此处需传一个集合,整个集合需有一个最顶级的父级
然后数据源就处理好了。在前端控件上绑定即可。但是在列那块的数据,需使用TreeNode.XXX来表示
接下来是FirstColumnInfo,顾名思义,就是首列的意思。在树形的DataGrid控件中,首列以树结构进行展示是通过框架自己添加进去的。框架提供了2个首列。一个是自定义的绑定自己类中树形的首列。二个是自动编号的首列。看大家的业务需求。
三、其他
1、DataGridGroupByBehavior
<corewindow:MainWindowBase x:Class="test.MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:corewindow="Vampirewal.Windows"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
Title="MainWindow"
Width="800"
Height="450"
//2021-12-2 新增
xmlns:VBeh="Vampirewal.Behaviors"
Background="#2F3437"
BorderBrush="#373C3F"
DataContext="{Binding Source={StaticResource Locator}, Path=MainViewModel}"
IsOpenWindowSize="True"
LeftMenuMaxWidth="300"
MainAreaHeight="50"
mc:Ignorable="d">
<Grid>
<DataGrid ItemsSource="{Binding Equips}">
<i:Interaction.Behaviors>
//此处的city可替换成你想要进行分组的那个字段值或如果需要在分组中再分组,这个字符串就用-进行分割就行
//如果分隔符写了不是-的,不会报错,但是会找不到这个属性,分组的名称是空的
<VBeh:DataGridGroupByBehavior SetGroupByProrName="Province-City" />
</i:Interaction.Behaviors>
</DataGrid>
</Grid>
</corewindow:MainWindowBase>