基于WPF重复造轮子,写一款数据库文档管理工具(一)

a83129e836ead56b5fecddb9fe3a3dd8.png

项目背景

公司业务历史悠久且复杂,数据库的表更是多而繁杂,每次基于老业务做功能开发都需要去翻以前的表和业务代码。需要理解旧的表的用途以及包含的字段的含义,表少还好说,但是表一多这就很浪费时间,而且留下来的文档都是残缺不全,每次查一些表的含义都要捯饬很久。在网上搜索关于数据库文档管理工具搜到最多的就是Screw和DBCHM,一个是基于Java的工具、另一个则是bug很多,表一多就一直转圈圈进不去。所以自己就动手开发了这款SmartSQL的工具。

它是一款基于.Net 4.6.1、WPF开发的一款数据库文档管理,不仅支持多种数据库(SQLServer、MySQL、PostgreSQL、SQLite)表、视图、存储过程的查询管理,还支持对其进行导出成离线文档,支持的文档包括CHM、Word、Excel、PDF、HTML、Xml、Json、MarkDown等多种格式。

现在将它开源分享出来,供更多的小伙伴使用和参考学习(文末附开源地址)。

64813beb0bf69b457c807c2f4b7d6ecb.png

技术栈

  • .Net 4.6.1

  • WPF

  • HandyControl

  • SqlSugar

  • AvalonEdit

  • SharpVectors

HandyControl是一款非常优秀的WPF框架,做出来的页面都很漂亮,所以我们选择使用它。

Nuget中引用HandyControl:

592b41094da4ff7f81f95c31f450b53a.png

一.菜单栏

f9c710a9fc1072418350a88d83ad64a8.png

然后我们要实现一个基于WPF边框上的菜单栏,刚好HandyControl中有这么一个菜单栏的控件,
下面就是实现菜单栏的方法:

<hc:GlowWindow.NonClientAreaContent><StackPanel Height="29" Margin="25,0,0,0"><Menu HorizontalAlignment="Left"><MenuItemx:Name="SwitchMenu"Cursor="Hand"FontWeight="Bold"Foreground="{DynamicResource DarkPrimaryBrush}"Header="选择连接"><MenuItem.Icon><PathData="{StaticResource DownGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon><MenuItem.ItemTemplate><HierarchicalDataTemplate><MenuItemWidth="160"Margin="0"Padding="0"HorizontalAlignment="Left"VerticalAlignment="Stretch"Click="SwitchMenu_Click"Cursor="Hand"FontWeight="Normal"Header="{Binding ConnectName}"><MenuItem.Icon><svgc:SvgViewboxWidth="16"Height="16"HorizontalAlignment="Left"IsHitTestVisible="False"Source="{Binding Icon}" /></MenuItem.Icon></MenuItem></HierarchicalDataTemplate></MenuItem.ItemTemplate></MenuItem><MenuItemName="MenuConnect"Cursor="Hand"FontWeight="Bold"Foreground="{DynamicResource DarkPrimaryBrush}"Header="文件"><MenuItem.Icon><PathData="{StaticResource FileGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon><MenuItemName="AddConnect"Click="AddConnect_OnClick"FontWeight="Normal"Header="新建连接"><MenuItem.Icon><PathData="{StaticResource NewConnectGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon></MenuItem><MenuItemName="ImportMark"Click="ImportMark_OnClick"FontWeight="Normal"Header="导入备注"><MenuItem.Icon><PathData="{StaticResource ImportGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon></MenuItem><MenuItemName="ExportDoc"Click="ExportDoc_OnClick"FontWeight="Normal"Header="导出文档"><MenuItem.Icon><PathData="{StaticResource ExportGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon></MenuItem></MenuItem><MenuItemName="MenuGroup"Click="MenuGroup_OnClick"Cursor="Hand"FontWeight="Bold"Foreground="{DynamicResource DarkPrimaryBrush}"Header="分组"><MenuItem.Icon><PathData="{StaticResource GroupGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon></MenuItem><MenuItemName="MenuSetting"Click="MenuSetting_OnClick"Cursor="Hand"FontWeight="Bold"Foreground="{DynamicResource DarkPrimaryBrush}"Header="设置"><MenuItem.Icon><PathData="{StaticResource SettingGeometry}"Fill="{DynamicResource DarkPrimaryBrush}"Stretch="Uniform" /></MenuItem.Icon></MenuItem><MenuItemName="MenuAbout"Click="MenuAbout_OnClick"Cursor="Hand"FontWeight="Bold"Foreground="{DynamicResource DarkPrimaryBrush}"Header="关于"><MenuItem.Icon><PathData="{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图形:

<svgc:SvgViewboxWidth="16"Height="16"HorizontalAlignment="Left"IsHitTestVisible="False"Source="{Binding Icon}" />

二.左侧菜单栏

然后就是左侧的菜单栏,我们要实现一个数据库的选择和数据库对象的搜索,可以搜索相关表、视图、存储过程等对象。
首先我们要对我们的主界面进行一个简单的1:1:1的竖向布局,分别为左侧菜单栏、中间可以移动的分隔栏、右面的主界面:

<!--  Main区域  -->
<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控件进行实现这样一个功能,下面是相关代码:

<DockPanel Grid.Row="0" Grid.Column="0"><hc:SimplePanel><BorderMargin="5,5,0,5"Background="{DynamicResource RegionBrush}"CornerRadius="{Binding CornerRadius}"><GridHeight="Auto"Margin="5"Background="Transparent"><TextBox x:Name="HidSelectDatabase" Visibility="Hidden" /><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="8*" /><ColumnDefinition Width="1*" MinWidth="30" /></Grid.ColumnDefinitions><ComboBoxx:Name="SelectDatabase"Height="30"VerticalAlignment="Top"HorizontalContentAlignment="Stretch"hc:BorderElement.CornerRadius="5"hc:InfoElement.Placeholder="请选择数据库"Cursor="Hand"IsTextSearchEnabled="True"SelectionChanged="SelectDatabase_OnSelectionChanged"Style="{StaticResource ComboBoxExtend}"Text="{Binding DbName}"><ComboBox.ItemTemplate><DataTemplate><StackPanel VerticalAlignment="Center" Orientation="Horizontal"><ImageWidth="11"Height="15"Source="/SmartSQL;component/Resources/Img/dataBase.ico" /><TextBlockMargin="5,0,0,0"HorizontalAlignment="Center"VerticalAlignment="Center"Text="{Binding DbName}" /></StackPanel></DataTemplate></ComboBox.ItemTemplate></ComboBox><ButtonName="BtnFresh"Grid.Column="2"Margin="0,0,0,0"Padding="4"VerticalAlignment="Top"Background="Transparent"BorderThickness="0"Click="BtnFresh_OnClick"Cursor="Hand"><Button.Content><Image Source="/SmartSQL;component/Resources/Img/Refresh.png" Stretch="Fill" /></Button.Content></Button></Grid><hc:SearchBarx:Name="SearchMenu"Height="30"Margin="0,34,0,0"Padding="5,0,5,0"VerticalAlignment="Top"HorizontalContentAlignment="Stretch"hc:BorderElement.CornerRadius="5"hc:InfoElement.Placeholder="搜索数据表/视图/存储过程"FontSize="13"ShowClearButton="True"Style="{StaticResource SearchBarPlus}"TextChanged="SearchMenu_OnTextChanged" /><TabControlx:Name="TabLeftType"Margin="0,65,0,40"SelectionChanged="TabLeftType_OnSelectionChanged"Style="{StaticResource TabControlInLine}"><TabItemx:Name="TabAllData"Cursor="Hand"Header="全部"IsSelected="True" /><TabItemx:Name="TabGroupData"Cursor="Hand"Header="分组"IsSelected="False" /><!--<TabItemx:Name="TabFavData"Cursor="Hand"Header="收藏"IsSelected="False" />--></TabControl><TreeViewx:Name="TreeViewTables"Margin="0,100,0,0"VerticalAlignment="Top"BorderThickness="0"ItemsSource="{Binding TreeViewData}"SelectedItemChanged="SelectedTable_OnClick"><TreeView.ItemContainerStyle><Style BasedOn="{StaticResource TreeViewItemBaseStyle}" TargetType="{x:Type TreeViewItem}"><Setter Property="IsExpanded" Value="{Binding IsExpanded}" /><Setter Property="FontWeight" Value="{Binding FontWeight}" /><Setter Property="FontSize" Value="12" /><Setter Property="Visibility" Value="{Binding Visibility}" /><Setter Property="Foreground" Value="{Binding TextColor}" /><Setter Property="Cursor" Value="Hand" /><!--  禁止水平滚动条自动滚动  --><EventSetter Event="RequestBringIntoView" Handler="EventSetter_OnHandler" /><Style.Triggers><Trigger Property="IsSelected" Value="True"><Setter Property="FontWeight" Value="Bold" /></Trigger></Style.Triggers>
</Style></TreeView.ItemContainerStyle><TreeView.ContextMenu><!--  右键菜单  --><ContextMenu Visibility="Visible"><MenuItemx:Name="MenuSelectedItem"Padding="5,0,5,0"VerticalAlignment="Center"Click="MenuSelectedItem_OnClick"Cursor="Hand"Header="复制对象名" /></ContextMenu></TreeView.ContextMenu><TreeView.ItemTemplate><HierarchicalDataTemplate DataType="{x:Type models:TreeNodeItem}" ItemsSource="{Binding Children}"><StackPanel Orientation="Horizontal"><svgc:SvgViewboxWidth="12"Height="12"Margin="0,0,5,0"HorizontalAlignment="Left"Source="{Binding Icon}" /><TextBlockVerticalAlignment="Center"FontSize="12"Text="{Binding DisplayName}"ToolTip="{Binding DisplayName}" /></StackPanel></HierarchicalDataTemplate></TreeView.ItemTemplate></TreeView><Gridx:Name="NoDataText"Margin="0,100,0,5"HorizontalAlignment="Stretch"Background="White"Cursor="Arrow"><local:NoDataAreax:Name="NoDataAreaText"Margin="0"HorizontalAlignment="Center"ShowType="All" /></Grid><GridMargin="0"VerticalAlignment="Bottom"Visibility="Hidden"><Grid.ColumnDefinitions><ColumnDefinition Width="4*" /><ColumnDefinition Width="6*" /><ColumnDefinition Width="Auto" /></Grid.ColumnDefinitions><Grid><ComboBoxx:Name="CbTargetConnect"Height="26"VerticalAlignment="Bottom"HorizontalContentAlignment="Left"hc:InfoElement.Placeholder="目标连接"Cursor="Hand"DisplayMemberPath="ConnectName"IsTextSearchEnabled="True"SelectedValuePath="DbMasterConnectString"SelectionChanged="CbTargetConnect_OnSelectionChanged"Style="{StaticResource ComboBoxExtend}" /></Grid><Grid Grid.Column="1" Margin="5,0,0,0"><ComboBoxx:Name="CbTargetDatabase"MinWidth="50"VerticalAlignment="Bottom"HorizontalContentAlignment="Left"hc:InfoElement.Placeholder="目标数据库"Cursor="Hand"IsTextSearchEnabled="True"Style="{StaticResource ComboBoxExtend}" /></Grid><Grid Grid.Column="2"><!--  差异比较按钮  --><Buttonx:Name="BtnCompare"Height="30"Margin="5,5,0,0"HorizontalAlignment="Right"hc:BorderElement.CornerRadius="6"hc:IconElement.Geometry="{StaticResource CompareGeometry}"Click="BtnCompare_OnClick"Content="差异比较"Cursor="Hand" /></Grid></Grid><!--  数据加载Loading  --><hc:LoadingLinex:Name="LoadingLine"Margin="0,0,0,0"Visibility="Collapsed" /></Grid></Border></hc:SimplePanel></DockPanel>

在这里我没有详细介绍底层c#的相关代码,里面逻辑有些复杂感兴趣的可以去我的开源项目中学习。在上面的左侧菜单代码中,我们使用的不仅有TreeView控件、也有ContextMenuhc:LoadingLine等控件,还有自己写的自定义控件。

其实WPF要比WinForm好用不少,不仅支持MVVM数据绑定还支持灵活的页面渲染,自从用了WPF再也不用WinForm了。

今天分享暂时到这里,下一篇将介绍DataGrid表格数据绑定及相关条件搜索。下面是工具的开源地址,感兴趣的可以Clone下来学习一下。码砖不易,喜欢的麻烦点下Star.

开源地址

https://gitee.com/izhaofu/SmartSQL


cdeb539a0bbb232f99ffba5b45e41c74.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]GitBook使用教程收藏

GitBook使用教程 最简单的方式就是使用GitBook编辑器&#xff0c;没有什么难度&#xff0c;后面的教程主要针对命令行的方式 PS&#xff1a;GitBook的book页面默认没有download按钮的 需要到设置中打开&#xff0c;打开后再次publish生效 同步GitHub 更新失败&#xff0c;无法…

二 面向对象三大特性

一 继承与派生 一、继承定义 二、继承与抽象的关系 三、继承与重用性 四、派生 五、组合与重用性 六、接口与归一化设计 七、抽象类 八、继承实现的原理 九、子类中调用父类的方法 二 多态与多态性 一、多态 二、多态性 三 封装 一、封装定义 二、特性(property) 三、封装与扩展…

CSS3新属性

边框&#xff1a; border-radius 用于创建圆角 div { border:2px solid; border-radius:25px; -moz-border-radius:25px; /* Old Firefox */ } box-shadow 用于向方框添加阴影 div { box-shadow: 10px 10px 5px #888888; } border-image 使用图片来创建边框 div { border-image…

Android实用笔记——使用Spinner实现下拉列表

2019独角兽企业重金招聘Python工程师标准>>> 1、编辑activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"mat…

基于.NET 6 的开源访客管理系统

简单介绍一下系统功能系统用于简化访客登记、查询、保存。传统的登记方式&#xff0c;不仅浪费纸张&#xff0c;而且还面临保存的问题&#xff0c;查阅不方便。该系统为了在疫情期间能很好管理访客登记做好风险管控,同时可以整合智能设备做到自动确认并跟踪访客的行动轨迹,该项…

完整的产品管理工作流程

产品经理的工作具体会落实到工作流程中&#xff0c;所以工作流程很大程度上会体现工作层次。很多白领产品经理&#xff0c;多年来在一个低层次的流程中转圈——理需求、画原型、写文档、管项目、验收上线&#xff0c;一个版本上线之后立刻对下一个版本理需求、画原型、写文档、…

java爬虫-简单爬取网页图片

刚刚接触到“爬虫”这个词的时候是在大一&#xff0c;那时候什么都不明白&#xff0c;但知道了百度、谷歌他们的搜索引擎就是个爬虫。 现在大二。再次燃起对爬虫的热爱&#xff0c;查阅资料&#xff0c;知道常用java、python语言编程&#xff0c;这次我选择了java。在网上查找的…

Windows Server 2016-图形化迁移FSMO角色

上章节我们简单介绍了三种不同方式查看FSMO主机角色信息&#xff0c;在开篇之前我们简单回顾一下FSMO五种操作主机角色&#xff1a;林范围操作主机角色有两种&#xff0c;分别是 架构主机角色&#xff08;Schema Master&#xff09;和 域命名主机角色&#xff08;Domain Naming…

[转]互联网最大谣言:程序员35岁必淘汰?今天我就来击碎他

朋友&#xff0c;只要你是程序员&#xff0c;你一定知道996和“程序员35岁必死”的言论。 这两个话题在互联网上的讨论一次比一次激烈。 996工作制&#xff0c;众所周知&#xff0c;每天早上9点到岗&#xff0c;一直待到晚上9点&#xff0c;每周工作6天&#xff0c;很多互联网公…

【ArcGIS微课1000例】0057:将多波段栅格(影像.tif)背景设置为无数据nodata的方法

本文讲解将多波段栅格(影像.tif)背景设置为无数据nodata的方法。 文章目录 一、背景值识别二、背景值去除【推荐阅读】: 【ArcGIS微课1000例】0056:将单波段栅格背景设置为无数据NoData的方法 一、背景值识别 可以用【识别】工具来获取影像数据的背景值。 在背景上单击,…

华为HCIA认证H12-811题库新增

801、[单选题]178/832、在系统视图下键入什么命令可以切换到用户视图? A quit B souter C system-view D user-view 试题答案&#xff1a;A 试题解析&#xff1a;在系统视图下键入quit命令退出到用户视图。因此答案选A。 802、[单选题]“网络管理员在三层交换机上创建了V…

经典Java微服务架构教程 微服务从开发到部署

图书目录脑图&#xff1a; 本书根据开源项目整理&#xff0c;由于原在线文档无法正常使用&#xff0c;本人重新在Github上重新布署了一套在线文档。 书中讲解非常详细&#xff0c;并且有在线的视频教程&#xff0c;另有在线文档和在线的源码。 书中的代码由于PDF排版问题可能显…

linux下redis安装

转自&#xff1a;http://blog.java1234.com/blog/articles/311.html Redis从一开始就只支持Linux&#xff0c;后面虽然有团队搞出Window版本&#xff0c;但是我还是建议大伙安装到Linux中。 准备工作 &#xff08;wm VirtualBox&#xff09; VMware 以及Xshell https://redis…

Quartz.NET simple_demo

Quartz.NET是一个开源的作业调度框架&#xff0c;非常适合在平时的工作中&#xff0c;定时轮询数据库同步&#xff0c;定时邮件通知&#xff0c;定时处理数据等。 Quartz.NET允许开发人员根据时间间隔&#xff08;或天&#xff09;来调度作业。它实现了作业和触发器的多对多关系…

Hello Playwright:(9)执行 JavaScript 代码

Playwright 提供了大量的 API 用于与页面元素交互&#xff0c;但是在某些场景下还是不能完全满足要求。比如我们需要获得包括元素本身的 HTML&#xff0c;但是目前只有下列 API :InnerHTMLAsync 返回元素内的 HTML 内容InnerTextAsync 返回元素内的文本内容而使用 JavaScript 执…

【PhotoScan精品教程】photoscan无法启动此程序,因为计算机中丢失cholmod.dll解决办法

安装完航测软件photoscan&#xff0c;打开时提示&#xff1a;无法启动此程序&#xff0c;因为计算机中丢失 cholmod.dll解决办法。 错误提示&#xff1a; 解决办法&#xff1a; 并不是缺少该动态链接库文件&#xff0c;而是补丁文件拷贝错了。

什么是中台?企业为什么要建中台?从数据中台到AI中台。

从去年开始&#xff0c;好像就有一只无形的手一直将我与“微服务”、“平台化”、“中台化”撮合在一起&#xff0c;给我带来了很多的困扰和思考与收获。 故事的开始源于去年的技术雷达峰会&#xff0c;我在会上做了一场关于平台崛起的主题分享&#xff08;《The Rise of Plat…

【GlobalMapper精品教程】035:用CASS自带数据创建高程地形、等高线教程

本文讲述globalmapper用CASS自带数据创建高程地形、等高线教程。 文章目录 1. 坐标生成点2. 点转高程格网3. 生成等高线4. 保存等高线CASS自带等高线数据dgx.dat预览:包含点号、编码、东坐标、北坐标、高程5列,可以不用做任何修改,在Globalmapper中生成点。 1. 坐标生成点 …

SaaS产品的免费试用到底该怎么做

”SaaS产品的免费试用&#xff0c;绝不仅仅只是开放产品试用期这么简单&#xff0c;很多企业并没有重视免费试用模式的搭建和转化路径“ 很多SaaS厂商的产品都会提供免费试用的机会&#xff0c;虽然试用的最终目标是促成用户为产品价值付费&#xff0c;但是很多SaaS厂商在开放系…

【.NET6+WPF】WPF使用prism框架+Unity IOC容器实现MVVM双向绑定和依赖注入

前言&#xff1a;在C/S架构上&#xff0c;WPF无疑已经是“桌面一霸”了。在.NET生态环境中&#xff0c;很多小伙伴还在使用Winform开发C/S架构的桌面应用。但是WPF也有很多年的历史了&#xff0c;并且基于MVVM的开发模式&#xff0c;受到了很多开发者的喜爱。并且随着工业化的进…