基于WPF重复造轮子,写一款数据库文档管理工具(一)
项目背景公司业务历史悠久且复杂,数据库的表更是多而繁杂,每次基于老业务做功能开发都需要去翻以前的表和业务代码。需要理解旧的表的用途以及包含的字段的含义,表少还好说,但是表一多这就很浪费时间,而且留下来的文档都是残缺不全,每次查一些表的含义都要捯饬很久。在网上搜索关于数据库文档管理工具搜到最多的就是Screw和DBCHM,一个是基于Java的工具、另一个则是bug很多,表一多就一直转圈圈进不去。所以自己就动手开发了这款SmartSQL的工具。
https://img2022.cnblogs.com/blog/627089/202207/627089-20220731162025265-1116344830.png
它是一款基于.Net 4.6.1、WPF开发的一款数据库文档管理,不仅支持多种数据库(SQLServer、MySQL、PostgreSQL、SQLite)表、视图、存储过程的查询管理,还支持对其进行导出成离线文档,支持的文档包括CHM、Word、Excel、PDF、HTML、Xml、Json、MarkDown等多种格式。
现在将它开源分享出来,供更多的小伙伴使用和参考学习(文末附开源地址)。
技术栈
[*].Net 4.6.1
[*]WPF
[*]HandyControl
[*]SqlSugar
[*]AvalonEdit
[*]SharpVectors
HandyControl是一款非常优秀的WPF框架,做出来的页面都很漂亮,所以我们选择使用它。
Nuget中引用HandyControl:
https://img2022.cnblogs.com/blog/627089/202207/627089-20220731160825057-268841996.png
一.菜单栏
https://img2022.cnblogs.com/blog/627089/202207/627089-20220731162248818-1700510450.png
然后我们要实现一个基于WPF边框上的菜单栏,刚好HandyControl中有这么一个菜单栏的控件,
下面就是实现菜单栏的方法:
`
<hc:GlowWindow.NonClientAreaContent>
<StackPanel Height="29" Margin="25,0,0,0">
<Menu HorizontalAlignment="Left">
<MenuItem
x:Name="SwitchMenu"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="选择连接">
<MenuItem.Icon>
<Path
Data="{StaticResource DownGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
<MenuItem.ItemTemplate>
<HierarchicalDataTemplate>
<MenuItem
Width="160"
Margin="0"
Padding="0"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Click="SwitchMenu_Click"
Cursor="Hand"
FontWeight="Normal"
Header="{Binding ConnectName}">
<MenuItem.Icon>
<svgc:SvgViewbox
Width="16"
Height="16"
HorizontalAlignment="Left"
IsHitTestVisible="False"
Source="{Binding Icon}" />
</MenuItem.Icon>
</MenuItem>
</HierarchicalDataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem
Name="MenuConnect"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="文件">
<MenuItem.Icon>
<Path
Data="{StaticResource FileGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
<MenuItem
Name="AddConnect"
Click="AddConnect_OnClick"
FontWeight="Normal"
Header="新建连接">
<MenuItem.Icon>
<Path
Data="{StaticResource NewConnectGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="ImportMark"
Click="ImportMark_OnClick"
FontWeight="Normal"
Header="导入备注">
<MenuItem.Icon>
<Path
Data="{StaticResource ImportGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="ExportDoc"
Click="ExportDoc_OnClick"
FontWeight="Normal"
Header="导出文档">
<MenuItem.Icon>
<Path
Data="{StaticResource ExportGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem
Name="MenuGroup"
Click="MenuGroup_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="分组">
<MenuItem.Icon>
<Path
Data="{StaticResource GroupGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="MenuSetting"
Click="MenuSetting_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="设置">
<MenuItem.Icon>
<Path
Data="{StaticResource SettingGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="MenuAbout"
Click="MenuAbout_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="关于">
<MenuItem.Icon>
<Path
Data="{StaticResource InfoGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
</Menu>
</StackPanel>
</hc:GlowWindow.NonClientAreaContent>其中有个小插曲,在WPF中是默认不支持svg图形的,所以我们需要引用一个组件:SharpVectors,它的使用方法是这样的,引用svg界面需要引入下面语句:
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
然后引用要显示的svg图形:
二.左侧菜单栏
然后就是左侧的菜单栏,我们要实现一个数据库的选择和数据库对象的搜索,可以搜索相关表、视图、存储过程等对象。
首先我们要对我们的主界面进行一个简单的1:1:1的竖向布局,分别为左侧菜单栏、中间可以移动的分隔栏、右面的主界面:
<Grid x:Name="GridMain" Background="{StaticResource CloudDrawingBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.3*" MinWidth="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="6.6*" />
</Grid.ColumnDefinitions>
</Grid>现在我们要实现一个左侧树形的菜单栏,我们使用的是WPF里面的TreeView控件进行实现这样一个功能,下面是相关代码:
<hc:GlowWindow.NonClientAreaContent>
<StackPanel Height="29" Margin="25,0,0,0">
<Menu HorizontalAlignment="Left">
<MenuItem
x:Name="SwitchMenu"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="选择连接">
<MenuItem.Icon>
<Path
Data="{StaticResource DownGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
<MenuItem.ItemTemplate>
<HierarchicalDataTemplate>
<MenuItem
Width="160"
Margin="0"
Padding="0"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Click="SwitchMenu_Click"
Cursor="Hand"
FontWeight="Normal"
Header="{Binding ConnectName}">
<MenuItem.Icon>
<svgc:SvgViewbox
Width="16"
Height="16"
HorizontalAlignment="Left"
IsHitTestVisible="False"
Source="{Binding Icon}" />
</MenuItem.Icon>
</MenuItem>
</HierarchicalDataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem
Name="MenuConnect"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="文件">
<MenuItem.Icon>
<Path
Data="{StaticResource FileGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
<MenuItem
Name="AddConnect"
Click="AddConnect_OnClick"
FontWeight="Normal"
Header="新建连接">
<MenuItem.Icon>
<Path
Data="{StaticResource NewConnectGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="ImportMark"
Click="ImportMark_OnClick"
FontWeight="Normal"
Header="导入备注">
<MenuItem.Icon>
<Path
Data="{StaticResource ImportGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="ExportDoc"
Click="ExportDoc_OnClick"
FontWeight="Normal"
Header="导出文档">
<MenuItem.Icon>
<Path
Data="{StaticResource ExportGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem
Name="MenuGroup"
Click="MenuGroup_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="分组">
<MenuItem.Icon>
<Path
Data="{StaticResource GroupGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="MenuSetting"
Click="MenuSetting_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="设置">
<MenuItem.Icon>
<Path
Data="{StaticResource SettingGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="MenuAbout"
Click="MenuAbout_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="关于">
<MenuItem.Icon>
<Path
Data="{StaticResource InfoGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
</Menu>
</StackPanel>
</hc:GlowWindow.NonClientAreaContent><hc:GlowWindow.NonClientAreaContent>
<StackPanel Height="29" Margin="25,0,0,0">
<Menu HorizontalAlignment="Left">
<MenuItem
x:Name="SwitchMenu"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="选择连接">
<MenuItem.Icon>
<Path
Data="{StaticResource DownGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
<MenuItem.ItemTemplate>
<HierarchicalDataTemplate>
<MenuItem
Width="160"
Margin="0"
Padding="0"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Click="SwitchMenu_Click"
Cursor="Hand"
FontWeight="Normal"
Header="{Binding ConnectName}">
<MenuItem.Icon>
<svgc:SvgViewbox
Width="16"
Height="16"
HorizontalAlignment="Left"
IsHitTestVisible="False"
Source="{Binding Icon}" />
</MenuItem.Icon>
</MenuItem>
</HierarchicalDataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem
Name="MenuConnect"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="文件">
<MenuItem.Icon>
<Path
Data="{StaticResource FileGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
<MenuItem
Name="AddConnect"
Click="AddConnect_OnClick"
FontWeight="Normal"
Header="新建连接">
<MenuItem.Icon>
<Path
Data="{StaticResource NewConnectGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="ImportMark"
Click="ImportMark_OnClick"
FontWeight="Normal"
Header="导入备注">
<MenuItem.Icon>
<Path
Data="{StaticResource ImportGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="ExportDoc"
Click="ExportDoc_OnClick"
FontWeight="Normal"
Header="导出文档">
<MenuItem.Icon>
<Path
Data="{StaticResource ExportGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem
Name="MenuGroup"
Click="MenuGroup_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="分组">
<MenuItem.Icon>
<Path
Data="{StaticResource GroupGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="MenuSetting"
Click="MenuSetting_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="设置">
<MenuItem.Icon>
<Path
Data="{StaticResource SettingGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Name="MenuAbout"
Click="MenuAbout_OnClick"
Cursor="Hand"
FontWeight="Bold"
Foreground="{DynamicResource DarkPrimaryBrush}"
Header="关于">
<MenuItem.Icon>
<Path
Data="{StaticResource InfoGeometry}"
Fill="{DynamicResource DarkPrimaryBrush}"
Stretch="Uniform" />
</MenuItem.Icon>
</MenuItem>
</Menu>
</StackPanel>
</hc:GlowWindow.NonClientAreaContent>
<Grid x:Name="GridMain" Background="{StaticResource CloudDrawingBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.3*" MinWidth="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="6.6*" />
</Grid.ColumnDefinitions>
</Grid>
<Grid x:Name="GridMain" Background="{StaticResource CloudDrawingBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.3*" MinWidth="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="6.6*" />
</Grid.ColumnDefinitions>
</Grid>
<Grid x:Name="GridMain" Background="{StaticResource CloudDrawingBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.3*" MinWidth="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="6.6*" />
</Grid.ColumnDefinitions>
</Grid>
<Grid x:Name="GridMain" Background="{StaticResource CloudDrawingBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.3*" MinWidth="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="6.6*" />
</Grid.ColumnDefinitions>
</Grid> 在这里我没有详细介绍底层c#的相关代码,里面逻辑有些复杂感兴趣的可以去我的开源项目中学习。在上面的左侧菜单代码中,我们使用的不仅有TreeView控件、也有ContextMenu、hc:LoadingLine等控件,还有自己写的自定义控件。
其实WPF要比WinForm好用不少,不仅支持MVVM数据绑定还支持灵活的页面渲染,自从用了WPF再也不用WinForm了。
今天分享暂时到这里,下一篇讲介绍DataGrid表格数据绑定及相关条件搜索。下面是工具的开源地址,感兴趣的可以Clone下来学习一下。码砖不易,喜欢的麻烦点下Star.
开源地址
https://gitee.com/izhaofu/SmartSQL
https://img2022.cnblogs.com/blog/627089/202207/627089-20220731163845669-2112065971.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]